1   /*
2   * Licensed to the Apache Software Foundation (ASF) under one or more
3   * contributor license agreements.  See the NOTICE file distributed with
4   * this work for additional information regarding copyright ownership.
5   * The ASF licenses this file to You under the Apache License, Version 2.0
6   * (the "License"); you may not use this file except in compliance with
7   * the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17  package org.apache.jetspeed.page;
18  
19  import java.io.File;
20  import java.io.FileFilter;
21  import java.io.FileInputStream;
22  import java.io.FileNotFoundException;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.Writer;
27  import java.nio.channels.FileChannel;
28  import java.util.Iterator;
29  import java.util.Map;
30  
31  import javax.xml.parsers.SAXParserFactory;
32  import javax.xml.transform.Transformer;
33  import javax.xml.transform.TransformerConfigurationException;
34  import javax.xml.transform.TransformerException;
35  import javax.xml.transform.TransformerFactory;
36  import javax.xml.transform.sax.SAXTransformerFactory;
37  import javax.xml.transform.stream.StreamResult;
38  import javax.xml.transform.stream.StreamSource;
39  
40  import org.apache.commons.lang.StringUtils;
41  import org.apache.jetspeed.util.DirectoryHelper;
42  
43  
44  /***
45   * @author ddam
46   *
47   */
48  public class DirectoryXMLTransform extends DirectoryHelper
49  {
50      private SAXTransformerFactory transformerFactory;
51  
52      private SAXParserFactory saxFactory;
53      
54      private Map xsltMapping;
55      
56          public DirectoryXMLTransform(File base, Map extensionToXslt) {
57            super(base);
58            this.xsltMapping=extensionToXslt;
59            System.setProperty("javax.xml.transform.TransformerFactory",
60            "org.apache.xalan.processor.TransformerFactoryImpl");
61            System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
62            System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
63            transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
64            saxFactory = SAXParserFactory.newInstance();
65            saxFactory.setValidating(false);
66  
67          }
68          
69          protected void setBaseDirectory(File directory){
70              if(!directory.exists())
71              {
72                  directory.mkdirs();
73              }
74              
75              if(!directory.isDirectory())
76              {
77                  throw new IllegalArgumentException("DirectoryHelper(File) requires directory not a file.");
78              }
79              this.directory = directory;
80              
81          }
82  
83          private Transformer getXSLTForFile(File f){
84              String extension = StringUtils.substringAfterLast(f.getName(),".");
85              
86              if (!StringUtils.isEmpty(extension) && xsltMapping.containsKey(extension.toLowerCase())){
87                  
88                  Object t_obj = xsltMapping.get(extension.toLowerCase());
89                  if (t_obj instanceof Transformer){
90                      return (Transformer)t_obj;
91                  }
92                  if (t_obj instanceof String){
93                      String t_path = (String) t_obj;
94                      Transformer transformer; 
95                      try{
96                          transformer = transformerFactory.newTransformer(new StreamSource(t_path));    
97                          xsltMapping.put(extension, transformer);
98                          return transformer;
99                      } catch(TransformerConfigurationException e){
100                         
101                     }                    
102                 }
103             }
104             
105             return null;
106         }
107         
108         /***
109          * <p>
110          * copyFrom
111          * </p>
112          *
113          * @see org.apache.jetspeed.util.FileSystemHelper#copyFrom(java.io.File, java.io.FileFilter)
114          * @param directory
115          * @param fileFilter
116          * @throws IOException
117          */
118         public void copyFromAndTransform( File srcDirectory, FileFilter fileFilter ) throws IOException
119         {
120             if(!srcDirectory.isDirectory())
121             {
122                 throw new IllegalArgumentException("DirectoryHelper.copyFrom(File) requires directory not a file.");
123             }
124             copyFilesAndTransform(srcDirectory, directory, fileFilter);        
125 
126         }
127 
128         /***
129          * 
130          * <p>
131          * copyFiles
132          * </p>
133          *
134          * @param srcDir Source directory to copy from.
135          * @param dstDir Destination directory to copy to.
136          * @throws IOException
137          * @throws FileNotFoundException
138 
139          */
140         protected void copyFilesAndTransform(File srcDir, File dstDir, FileFilter fileFilter) throws IOException
141         {
142             FileChannel srcChannel = null;
143             FileChannel dstChannel = null;
144 
145             try
146             {
147             File[] children = srcDir.listFiles(fileFilter);
148             for(int i=0; i<children.length; i++)
149             {
150                 File child = children[i];
151                 if(child.isFile())
152                 {
153                     File toFile = new File(dstDir, child.getName());
154                     
155                     toFile.createNewFile();
156                     srcChannel = new FileInputStream(child).getChannel();
157                     
158                     Transformer transformer = getXSLTForFile(child);
159                     if (transformer != null){
160                         FileOutputStream f_out = new FileOutputStream(toFile);
161                         try{
162                             transformer.transform(new StreamSource(child), new StreamResult(f_out));
163                             f_out.flush();
164                             f_out.close();
165                         } catch (TransformerException e){
166                             System.out.println("Error transforming file "+child.getCanonicalPath());
167                         }
168                         
169                     } else {
170                         dstChannel = new FileOutputStream(toFile).getChannel();
171                         dstChannel.transferFrom(srcChannel, 0, srcChannel.size());  
172                         dstChannel.close();
173                     }
174                     
175                     srcChannel.close();
176                    
177                 }
178                 else
179                 {
180                     File newSubDir = new File(dstDir, child.getName());
181                     newSubDir.mkdir();
182                     copyFilesAndTransform(child, newSubDir, fileFilter);
183                 }
184             }
185             }
186             finally
187             {
188                 if ( srcChannel != null && srcChannel.isOpen() )
189                 {
190                     try
191                     {
192                         srcChannel.close();
193                     }
194                     catch (Exception e)
195                     {
196                         
197                     }
198                 }
199                 if ( dstChannel != null && dstChannel.isOpen() )
200                 {
201                     try
202                     {
203                         dstChannel.close();
204                     }
205                     catch (Exception e)
206                     {
207                         
208                     }
209                 }
210             }
211         }
212         
213         public void transform(Transformer transformer, InputStream in, Writer out) throws TransformerException
214         {
215             transformer.transform(new StreamSource(in), new StreamResult(out));
216         }
217 }