Coverage Report - org.mule.tools.schemadocs.SchemaDocsMain
 
Classes in this File Line Coverage Branch Coverage Complexity
SchemaDocsMain
11%
13/119
11%
5/46
3.214
SchemaDocsMain$1
0%
0/7
0%
0/8
3.214
 
 1  
 /*
 2  
  * $Id: SchemaDocsMain.java 11248 2008-03-07 13:41:25Z acooke $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.tools.schemadocs;
 12  
 
 13  
 import org.mule.util.IOUtils;
 14  
 
 15  
 import java.io.File;
 16  
 import java.io.FileOutputStream;
 17  
 import java.io.FilenameFilter;
 18  
 import java.io.IOException;
 19  
 import java.io.InputStream;
 20  
 import java.io.OutputStream;
 21  
 import java.io.OutputStreamWriter;
 22  
 import java.net.JarURLConnection;
 23  
 import java.net.MalformedURLException;
 24  
 import java.net.URL;
 25  
 import java.util.Arrays;
 26  
 import java.util.Enumeration;
 27  
 import java.util.Iterator;
 28  
 import java.util.LinkedList;
 29  
 import java.util.List;
 30  
 import java.util.jar.JarEntry;
 31  
 
 32  
 import javax.xml.parsers.ParserConfigurationException;
 33  
 import javax.xml.transform.Source;
 34  
 import javax.xml.transform.Templates;
 35  
 import javax.xml.transform.Transformer;
 36  
 import javax.xml.transform.TransformerException;
 37  
 import javax.xml.transform.TransformerFactory;
 38  
 import javax.xml.transform.stream.StreamResult;
 39  
 import javax.xml.transform.stream.StreamSource;
 40  
 
 41  
 import org.apache.commons.logging.Log;
 42  
 import org.apache.commons.logging.LogFactory;
 43  
 import org.springframework.core.io.Resource;
 44  
 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 45  
 
 46  
 
 47  
 public class SchemaDocsMain
 48  
 {
 49  
 
 50  
     public static final String BACKUP = ".bak";
 51  
     public static final String XSD = ".xsd";
 52  
     public static final String MULE = "mule";
 53  
     public static final String TAG = "tag";
 54  
     public static final String XSL_FILE = "rename-tag.xsl";
 55  2
     public static final List TARGET_PATH = Arrays.asList(new String[]{"tools", "schemadocs", "target"});
 56  2
     public static final String[] BLOCKED = new String[]{"wssecurity"};
 57  
 
 58  0
     protected final Log logger = LogFactory.getLog(getClass());
 59  
 
 60  
     public static void main(String[] args)
 61  
             throws IOException, TransformerException, ParserConfigurationException
 62  
     {
 63  0
         if (null == args || args.length != 3)
 64  
         {
 65  0
             throw new IllegalArgumentException("Needs 3 arguments: prefix, postfix and destination");
 66  
         }
 67  0
         new SchemaDocsMain(args[0], args[1], args[2]);
 68  0
     }
 69  
 
 70  
     public SchemaDocsMain(String prefix, String postfix, String normalizedPath)
 71  
             throws IOException, TransformerException, ParserConfigurationException
 72  0
     {
 73  0
         logger.info("Generating " + normalizedPath);
 74  0
         logger.debug("prefix: " + prefix);
 75  0
         logger.debug("postfix: " + postfix);
 76  0
         File normalized = inTargetDir(normalizedPath);
 77  0
         backup(normalized);
 78  0
         InputStream xslSource = IOUtils.getResourceAsStream(XSL_FILE, getClass());
 79  0
         if (null == xslSource)
 80  
         {
 81  0
             throw new IllegalStateException("Cannot open " + XSL_FILE);
 82  
         }
 83  0
         create(normalized, false);
 84  0
         OutputStream out = new FileOutputStream(normalized);
 85  0
         logger.debug("out: " + out);
 86  0
         OutputStreamWriter outWriter = new OutputStreamWriter(out);
 87  0
         IOUtils.copy(IOUtils.getResourceAsStream(prefix, getClass()), outWriter);
 88  0
         outWriter.flush();
 89  0
         processSchema(xslSource, out);
 90  0
         out.flush();
 91  0
         IOUtils.copy(IOUtils.getResourceAsStream(postfix, getClass()), outWriter);
 92  0
         outWriter.close();
 93  0
     }
 94  
 
 95  
     protected void create(File file, boolean dir) throws IOException
 96  
     {
 97  0
         if (!file.getParentFile().exists())
 98  
         {
 99  0
             create(file.getParentFile(), true);
 100  
         }
 101  0
         logger.debug("creating " + file);
 102  0
         if (dir)
 103  
         {
 104  0
             file.mkdir();
 105  
         }
 106  
         else
 107  
         {
 108  0
             file.createNewFile();
 109  
         }
 110  0
     }
 111  
 
 112  
     // if possible, and path not absolute, place in target directory
 113  
     protected File inTargetDir(String path)
 114  
     {
 115  0
         if (path.startsWith(File.separator))
 116  
         {
 117  0
             return new File(path);
 118  
         }
 119  
         else
 120  
         {
 121  0
             File dir = new File(".");
 122  0
             Iterator dirs = TARGET_PATH.iterator();
 123  0
             boolean foundPath = false;
 124  0
             while (dirs.hasNext())
 125  
             {
 126  0
                 File next = new File(dir, (String) dirs.next());
 127  0
                 if (next.exists())
 128  
                 {
 129  0
                     foundPath = true;
 130  0
                     dir = next;
 131  
                 }
 132  0
                 else if (foundPath)
 133  
                 {
 134  
                     // in this case we started down the path, but failed
 135  
                     // (this avoids us placing the file somewhere other than "target"
 136  
                     // to workaround, specify absolute path)
 137  0
                     throw new IllegalArgumentException("Could not find " + next + " while placing in target directory");
 138  
                 }
 139  0
             }
 140  0
             File target = new File(dir, path);
 141  0
             logger.info("Target: " + target);
 142  0
             return target;
 143  
         }
 144  
     }
 145  
 
 146  
     protected void processSchema(InputStream xslSource, OutputStream out)
 147  
             throws TransformerException, IOException, ParserConfigurationException
 148  
     {
 149  0
         TransformerFactory factory = TransformerFactory.newInstance();
 150  0
         Templates template = factory.newTemplates(new StreamSource(xslSource));
 151  0
         Transformer xformer = template.newTransformer();
 152  0
         Iterator urls = listSchema2().iterator();
 153  0
         while (urls.hasNext())
 154  
         {
 155  0
             URL url = (URL) urls.next();
 156  0
             String tag = tagFromFileName(url.getFile());
 157  0
             logger.info(tag + " : " + url);
 158  0
             xformer.setParameter(TAG, tag);
 159  0
             Source source = new StreamSource(url.openStream());
 160  0
             xformer.transform(source, new StreamResult(out));
 161  
 //            xformer.transform(source, new StreamResult(System.out));
 162  0
             out.flush();
 163  0
         }
 164  0
     }
 165  
 
 166  
     // this avoids using File objects since we may be dealing with classpath jars etc etc
 167  
     protected static String tagFromFileName(String name)
 168  
     {
 169  4
         String dropExtension = toLeftOf(name, ".", name);
 170  4
         String dropSlash = toRightOf(dropExtension, "/", dropExtension, true);
 171  4
         String dropBackslash = toRightOf(dropSlash, "\\", dropSlash, true);
 172  4
         return toRightOf(dropBackslash, "-", "mule", false);
 173  
     }
 174  
 
 175  
     protected static String toRightOf(String text, String delim, String deflt, boolean far)
 176  
     {
 177  12
         int index = far ? text.lastIndexOf(delim) : text.indexOf(delim);
 178  12
         if (index > -1)
 179  
         {
 180  8
             return text.substring(index+1);
 181  
         }
 182  
         else
 183  
         {
 184  4
             return deflt;
 185  
         }
 186  
     }
 187  
 
 188  
     protected static String toLeftOf(String text, String delim, String deflt)
 189  
     {
 190  4
         int index = text.lastIndexOf(delim);
 191  4
         if (index > -1)
 192  
         {
 193  4
             return text.substring(0, index);
 194  
         }
 195  
         else
 196  
         {
 197  0
             return deflt;
 198  
         }
 199  
     }
 200  
 
 201  
     // for some reason, this doesn't work
 202  
     protected List listSchema1() throws IOException
 203  
     {
 204  0
         PathMatchingResourcePatternResolver resolver =
 205  
                 new PathMatchingResourcePatternResolver(getClass().getClassLoader());
 206  0
         Resource[] resources = resolver.getResources("**/META-INF/*.xsd");
 207  0
         List list = new LinkedList();
 208  0
         for (int i = 0; i < resources.length; ++i)
 209  
         {
 210  0
             list.add(resources[i].getURL());
 211  
         }
 212  0
         return list;
 213  
     }
 214  
 
 215  
     // this is a bit ad-hoc, but seems to work efficiently
 216  
     // http://forum.java.sun.com/thread.jspa?threadID=286026&messageID=1119510
 217  
     protected List listSchema2() throws IOException
 218  
     {
 219  0
         ClassLoader loader = getClass().getClassLoader();
 220  0
         List files = new LinkedList();
 221  0
         Enumeration resources = loader.getResources("META-INF");
 222  0
         FilenameFilter filter =
 223  
                 new FilenameFilter() {
 224  0
                     public boolean accept(File dir, String name)
 225  
                     {
 226  0
                         if (name.startsWith(MULE) && name.endsWith(XSD))
 227  
                         {
 228  0
                             for (int i = 0; i < BLOCKED.length; ++i)
 229  
                             {
 230  0
                                 if (name.indexOf(BLOCKED[i]) > -1)
 231  
                                 {
 232  0
                                     return false;
 233  
                                 }
 234  
                             }
 235  0
                             return true;
 236  
                         }
 237  
                         else
 238  
                         {
 239  0
                             return false;
 240  
                         }
 241  
                     }
 242  
                 };
 243  0
         while (resources.hasMoreElements())
 244  
         {
 245  0
             URL url = (URL) resources.nextElement();
 246  0
             logger.debug("url: " + url);
 247  0
             if (url.toString().startsWith("jar:"))
 248  
             {
 249  0
                 readFromJar(url, files);
 250  
             }
 251  0
             else if ("file".equals(url.getProtocol()))
 252  
             {
 253  0
                 readFromDirectory(new File(url.getFile()), files, filter);
 254  
             }
 255  0
         }
 256  0
         return files;
 257  
     }
 258  
 
 259  
     // this is used from within idea
 260  
     protected void readFromDirectory(File dir, List files, FilenameFilter filter) throws MalformedURLException
 261  
     {
 262  0
         String[] names = dir.list(filter);
 263  0
         for (int i = 0; i < names.length; ++i)
 264  
         {
 265  0
             String name = names[i];
 266  0
             logger.debug("file: " + name);
 267  0
             files.add(new File(dir, name).toURL());
 268  
         }
 269  0
     }
 270  
 
 271  
     // this is used from within maven
 272  
     protected void readFromJar(URL jarUrl, List resources) throws IOException
 273  
     {
 274  0
         JarURLConnection jarConnection = (JarURLConnection) jarUrl.openConnection();
 275  0
         Enumeration entries = jarConnection.getJarFile().entries();
 276  0
         while (entries.hasMoreElements())
 277  
         {
 278  0
             JarEntry entry = (JarEntry) entries.nextElement();
 279  0
             String name = new File(entry.getName()).getName();
 280  0
             if (name.startsWith(MULE) && name.endsWith(XSD))
 281  
             {
 282  0
                 logger.debug("entry: " + entry);
 283  0
                 resources.add(new URL(jarUrl, entry.getName()));
 284  
             }
 285  0
         }
 286  0
   }
 287  
 
 288  
     protected void backup(File file) throws IOException
 289  
     {
 290  0
         if (file.exists())
 291  
         {
 292  0
             File backup = new File(file.getAbsoluteFile().getParent(), file.getName() + BACKUP);
 293  0
             if (backup.exists())
 294  
             {
 295  0
                 logger.debug("deleting " + backup.getCanonicalPath());
 296  0
                 backup.delete();
 297  
             }
 298  0
             logger.debug("renaming " + file.getCanonicalPath() + " to " + backup.getCanonicalPath());
 299  0
             file.renameTo(backup);
 300  
         }
 301  0
     }
 302  
 
 303  
 }