src/share/jaxws_classes/com/sun/tools/internal/jxc/ConfigReader.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.internal.jxc;
    28 import java.io.File;
    29 import java.io.IOException;
    30 import java.util.Collection;
    31 import java.util.HashMap;
    32 import java.util.HashSet;
    33 import java.util.List;
    34 import java.util.Map;
    35 import java.util.Set;
    36 import java.util.regex.Matcher;
    37 import java.util.regex.Pattern;
    39 import javax.xml.bind.SchemaOutputResolver;
    40 import javax.xml.parsers.ParserConfigurationException;
    41 import javax.xml.parsers.SAXParserFactory;
    42 import javax.xml.transform.Result;
    43 import javax.xml.transform.stream.StreamResult;
    44 import javax.xml.validation.ValidatorHandler;
    46 import javax.annotation.processing.ProcessingEnvironment;
    47 import javax.lang.model.element.TypeElement;
    48 import com.sun.tools.internal.jxc.gen.config.Config;
    49 import com.sun.tools.internal.jxc.gen.config.Schema;
    50 import com.sun.tools.internal.xjc.SchemaCache;
    51 import com.sun.tools.internal.xjc.api.Reference;
    52 import com.sun.tools.internal.xjc.util.ForkContentHandler;
    54 import org.xml.sax.ErrorHandler;
    55 import org.xml.sax.InputSource;
    56 import org.xml.sax.SAXException;
    57 import org.xml.sax.XMLReader;
    60 /**
    61  * This reads the config files passed by the user to annotation processing
    62  * and obtains a list of classes that need to be included
    63  * for a particular config from the set of classes passed
    64  * by the user to annotation processing.
    65  *
    66  * @author Bhakti Mehta (bhakti.mehta@sun.com)
    67  */
    68 public final class ConfigReader  {
    70     /**
    71      * The set of classes to be passed to XJC
    72      *
    73      */
    74     private final Set<Reference> classesToBeIncluded = new HashSet<Reference>();
    77     /**
    78      *  The SchemaOutputResolver used to generate the schemas
    79      */
    80     private final SchemaOutputResolver schemaOutputResolver;
    82     private final ProcessingEnvironment env;
    84     /**
    85      *
    86      * @param classes
    87      *      The set of classes passed to the AnnotationProcessor
    88      * @param xmlFile
    89      *      The configuration file.
    90      * @throws SAXException
    91      *      If this is thrown, the error has already been reported.
    92      * @throws IOException
    93      *     If any IO errors occur.
    94      */
    95     public ConfigReader(ProcessingEnvironment env, Collection<? extends TypeElement> classes, File xmlFile, ErrorHandler errorHandler) throws SAXException, IOException {
    96         this.env = env;
    97         Config config = parseAndGetConfig(xmlFile,errorHandler);
    98         checkAllClasses(config,classes);
    99         String path =   xmlFile.getAbsolutePath();
   100         String xmlPath = path.substring(0,path.lastIndexOf(File.separatorChar));
   101         schemaOutputResolver = createSchemaOutputResolver(config,xmlPath);
   103     }
   106     /**
   107      * This creates a regular expression
   108      * for the user pattern , matches the input classes
   109      * passed by the user and returns the final
   110      * list of classes that need to be included for a config file
   111      * after applying those patterns
   112      *
   113      */
   114     public Collection<Reference> getClassesToBeIncluded() {
   115         return classesToBeIncluded;
   116     }
   118     private void checkAllClasses(Config config, Collection<? extends TypeElement> rootClasses) {
   120         List<Pattern> includeRegexList = config.getClasses().getIncludes();
   121         List<Pattern>  excludeRegexList = config.getClasses().getExcludes();
   123         OUTER:
   124         for (TypeElement typeDecl : rootClasses) {
   126             String qualifiedName = typeDecl.getQualifiedName().toString();
   128             for (Pattern pattern : excludeRegexList) {
   129                 boolean match = checkPatternMatch(qualifiedName, pattern);
   130                 if (match)
   131                     continue OUTER; // excluded
   132             }
   134             for (Pattern pattern : includeRegexList) {
   135                 boolean match = checkPatternMatch(qualifiedName, pattern);
   136                 if (match) {
   137                     classesToBeIncluded.add(new Reference(typeDecl,env));
   138                     break;
   139                 }
   140             }
   141         }
   142     }
   144     /**
   145      * This returns the SchemaOutputResolver to generate the schemas
   146      */
   147     public SchemaOutputResolver getSchemaOutputResolver(){
   148         return schemaOutputResolver;
   149     }
   151     private SchemaOutputResolver createSchemaOutputResolver(Config config, String xmlpath) {
   152         File baseDir = new File(xmlpath, config.getBaseDir().getPath());
   153         SchemaOutputResolverImpl schemaOutputResolver = new SchemaOutputResolverImpl (baseDir);
   155         for( Schema schema : (List<Schema>)config.getSchema() ) {
   156             String namespace = schema.getNamespace();
   157             File location = schema.getLocation();
   158             schemaOutputResolver.addSchemaInfo(namespace,location);
   159         }
   160         return schemaOutputResolver;
   161     }
   163     /**
   164      * This will  check if the qualified name matches the pattern
   165      *
   166      * @param qualifiedName
   167      *      The qualified name of the TypeDeclaration
   168      * @param pattern
   169      *       The  pattern obtained from the users input
   170      *
   171      */
   172     private boolean checkPatternMatch(String qualifiedName, Pattern pattern) {
   173         Matcher matcher = pattern.matcher(qualifiedName);
   174         return matcher.matches();
   175     }
   179     /**
   180      * Lazily parsed schema for the binding file.
   181      */
   182     private static SchemaCache configSchema = new SchemaCache(Config.class.getResource("config.xsd"));
   185     /**
   186      * Parses an xml config file and returns a Config object.
   187      *
   188      * @param xmlFile
   189      *        The xml config file which is passed by the user to annotation processing
   190      * @return
   191      *        A non null Config object
   192      */
   193     private Config parseAndGetConfig (File xmlFile, ErrorHandler errorHandler) throws SAXException, IOException {
   194         XMLReader reader;
   195         try {
   196             SAXParserFactory factory = SAXParserFactory.newInstance();
   197             factory.setNamespaceAware(true);
   198             reader = factory.newSAXParser().getXMLReader();
   199         } catch (ParserConfigurationException e) {
   200             // in practice this will never happen
   201             throw new Error(e);
   202         }
   203         NGCCRuntimeEx runtime = new NGCCRuntimeEx(errorHandler);
   205         // set up validator
   206         ValidatorHandler validator = configSchema.newValidator();
   207         validator.setErrorHandler(errorHandler);
   209         // the validator will receive events first, then the parser.
   210         reader.setContentHandler(new ForkContentHandler(validator,runtime));
   212         reader.setErrorHandler(errorHandler);
   213         Config config = new Config(runtime);
   214         runtime.setRootHandler(config);
   215         reader.parse(new InputSource(xmlFile.toURL().toExternalForm()));
   216         runtime.reset();
   218         return config;
   219     }
   220     /**
   221      * Controls where the JAXB RI puts the generates
   222      * schema files.
   223      * @author
   224      *     Bhakti Mehta (bhakti.mehta@sun.com)
   225      */
   226     private static final class SchemaOutputResolverImpl extends SchemaOutputResolver{
   228         /**
   229          * Directory to which we put the rest of the files.
   230          * Never be null.
   231          */
   232         private final File baseDir;
   234         /**
   235          * Namespace URI to the location of the schema.
   236          * This captures what the user specifies.
   237          */
   238         private final Map<String,File> schemas = new HashMap<String,File>();
   241         /**
   242          * Decides where the schema file (of the given namespace URI)
   243          * will be written, and return it as a {@link Result} object.
   244          *
   245          */
   246         public Result createOutput( String namespaceUri, String suggestedFileName ) {
   248             // the user's preference takes a precedence
   249             if(schemas.containsKey(namespaceUri)) {
   250                 File loc = schemas.get(namespaceUri);
   251                 if(loc==null)   return null;    // specifically not to generate a schema
   253                 // create directories if necessary. we've already checked that the baseDir
   254                 // exists, so this should be no surprise to users.
   255                 loc.getParentFile().mkdirs();
   257                 return new StreamResult(loc);   // generate into a file the user specified.
   258             }
   260             // if the user didn't say anything about this namespace,
   261             // generate it into the default directory with a default name.
   263              File schemaFile = new File (baseDir, suggestedFileName);
   264              // The systemId for the result will be schemaFile
   265              return new StreamResult(schemaFile);
   266         }
   269         public SchemaOutputResolverImpl(File baseDir) {
   270             assert baseDir!=null;
   271             this.baseDir = baseDir;
   272         }
   274         public void addSchemaInfo(String namespaceUri, File location) {
   275             if (namespaceUri == null )
   276                 //generate elements in no namespace
   277                 namespaceUri = "";
   278             schemas.put(namespaceUri, location);
   280         }
   282     }
   283 }

mercurial