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.FileWriter;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.Writer;
28  import java.nio.channels.FileChannel;
29  import java.util.Iterator;
30  import java.util.Map;
31  
32  import javax.xml.parsers.SAXParserFactory;
33  import javax.xml.transform.Transformer;
34  import javax.xml.transform.TransformerConfigurationException;
35  import javax.xml.transform.TransformerException;
36  import javax.xml.transform.TransformerFactory;
37  import javax.xml.transform.sax.SAXTransformerFactory;
38  import javax.xml.transform.stream.StreamResult;
39  import javax.xml.transform.stream.StreamSource;
40  
41  import org.apache.commons.lang.StringUtils;
42  import org.apache.jetspeed.util.DirectoryHelper;
43  
44  
45  /***
46   * @author ddam
47   *
48   */
49  public class DirectoryXMLTransform extends DirectoryHelper
50  {
51      private SAXTransformerFactory transformerFactory;
52  
53      private SAXParserFactory saxFactory;
54      
55      private Map xsltMapping;
56      
57          public DirectoryXMLTransform(File base, Map extensionToXslt) {
58            super(base);
59            this.xsltMapping=extensionToXslt;
60            System.setProperty("javax.xml.transform.TransformerFactory",
61            "org.apache.xalan.processor.TransformerFactoryImpl");
62            System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
63            System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
64            transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
65            saxFactory = SAXParserFactory.newInstance();
66            saxFactory.setValidating(false);
67  
68          }
69          
70          protected void setBaseDirectory(File directory){
71              if(!directory.exists())
72              {
73                  directory.mkdirs();
74              }
75              
76              if(!directory.isDirectory())
77              {
78                  throw new IllegalArgumentException("DirectoryHelper(File) requires directory not a file.");
79              }
80              this.directory = directory;
81              
82          }
83  
84          private Transformer getXSLTForFile(File f){
85              String extension = StringUtils.substringAfterLast(f.getName(),".");
86              
87              if (!StringUtils.isEmpty(extension) && xsltMapping.containsKey(extension.toLowerCase())){
88                  
89                  Object t_obj = xsltMapping.get(extension.toLowerCase());
90                  if (t_obj instanceof Transformer){
91                      return (Transformer)t_obj;
92                  }
93                  if (t_obj instanceof String){
94                      String t_path = (String) t_obj;
95                      Transformer transformer; 
96                      try{
97                          transformer = transformerFactory.newTransformer(new StreamSource(t_path));    
98                          xsltMapping.put(extension, transformer);
99                          return transformer;
100                     } catch(TransformerConfigurationException e){
101                         
102                     }                    
103                 }
104             }
105             
106             return null;
107         }
108         
109         /***
110          * <p>
111          * copyFrom
112          * </p>
113          *
114          * @see org.apache.jetspeed.util.FileSystemHelper#copyFrom(java.io.File, java.io.FileFilter)
115          * @param directory
116          * @param fileFilter
117          * @throws IOException
118          */
119         public void copyFromAndTransform( File srcDirectory, FileFilter fileFilter ) throws IOException
120         {
121             if(!srcDirectory.isDirectory())
122             {
123                 throw new IllegalArgumentException("DirectoryHelper.copyFrom(File) requires directory not a file.");
124             }
125             copyFilesAndTransform(srcDirectory, directory, fileFilter);        
126 
127         }
128 
129         /***
130          * 
131          * <p>
132          * copyFiles
133          * </p>
134          *
135          * @param srcDir Source directory to copy from.
136          * @param dstDir Destination directory to copy to.
137          * @throws IOException
138          * @throws FileNotFoundException
139 
140          */
141         protected void copyFilesAndTransform(File srcDir, File dstDir, FileFilter fileFilter) throws IOException
142         {
143             FileChannel srcChannel = null;
144             FileChannel dstChannel = null;
145 
146             try
147             {
148             File[] children = srcDir.listFiles(fileFilter);
149             for(int i=0; i<children.length; i++)
150             {
151                 File child = children[i];
152                 if(child.isFile())
153                 {
154                     File toFile = new File(dstDir, child.getName());
155                     
156                     toFile.createNewFile();
157                     srcChannel = new FileInputStream(child).getChannel();
158                     
159                     Transformer transformer = getXSLTForFile(child);
160                     if (transformer != null){
161                         FileWriter f_out = new FileWriter(toFile);
162                         try{
163                             transformer.transform(new StreamSource(child), new StreamResult(f_out));
164                             f_out.flush();
165                             f_out.close();
166                         } catch (TransformerException e){
167                             System.out.println("Error transforming file "+child.getCanonicalPath());
168                         }
169                         
170                     } else {
171                         dstChannel = new FileOutputStream(toFile).getChannel();
172                         dstChannel.transferFrom(srcChannel, 0, srcChannel.size());  
173                         dstChannel.close();
174                     }
175                     
176                     srcChannel.close();
177                    
178                 }
179                 else
180                 {
181                     File newSubDir = new File(dstDir, child.getName());
182                     newSubDir.mkdir();
183                     copyFilesAndTransform(child, newSubDir, fileFilter);
184                 }
185             }
186             }
187             finally
188             {
189                 if ( srcChannel != null && srcChannel.isOpen() )
190                 {
191                     try
192                     {
193                         srcChannel.close();
194                     }
195                     catch (Exception e)
196                     {
197                         
198                     }
199                 }
200                 if ( dstChannel != null && dstChannel.isOpen() )
201                 {
202                     try
203                     {
204                         dstChannel.close();
205                     }
206                     catch (Exception e)
207                     {
208                         
209                     }
210                 }
211             }
212         }
213         
214         public void transform(Transformer transformer, InputStream in, Writer out) throws TransformerException
215         {
216             transformer.transform(new StreamSource(in), new StreamResult(out));
217         }
218 }