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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, 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 com.sun.tools.internal.jxc.ap.Options;
    29 import java.io.File;
    30 import java.io.IOException;
    31 import java.util.Collection;
    32 import java.util.HashMap;
    33 import java.util.HashSet;
    34 import java.util.List;
    35 import java.util.Map;
    36 import java.util.Set;
    37 import java.util.regex.Matcher;
    38 import java.util.regex.Pattern;
    40 import javax.xml.bind.SchemaOutputResolver;
    41 import javax.xml.parsers.ParserConfigurationException;
    42 import javax.xml.parsers.SAXParserFactory;
    43 import javax.xml.transform.Result;
    44 import javax.xml.transform.stream.StreamResult;
    45 import javax.xml.validation.ValidatorHandler;
    47 import javax.annotation.processing.ProcessingEnvironment;
    48 import javax.lang.model.element.TypeElement;
    49 import com.sun.tools.internal.jxc.gen.config.Config;
    50 import com.sun.tools.internal.jxc.gen.config.Schema;
    51 import com.sun.tools.internal.xjc.SchemaCache;
    52 import com.sun.tools.internal.xjc.api.Reference;
    53 import com.sun.tools.internal.xjc.util.ForkContentHandler;
    55 import com.sun.xml.internal.bind.v2.util.XmlFactory;
    56 import org.xml.sax.ErrorHandler;
    57 import org.xml.sax.InputSource;
    58 import org.xml.sax.SAXException;
    59 import org.xml.sax.XMLReader;
    62 /**
    63  * This reads the config files passed by the user to annotation processing
    64  * and obtains a list of classes that need to be included
    65  * for a particular config from the set of classes passed
    66  * by the user to annotation processing.
    67  *
    68  * @author Bhakti Mehta (bhakti.mehta@sun.com)
    69  */
    70 public final class ConfigReader  {
    72     /**
    73      * The set of classes to be passed to XJC
    74      *
    75      */
    76     private final Set<Reference> classesToBeIncluded = new HashSet<Reference>();
    79     /**
    80      *  The SchemaOutputResolver used to generate the schemas
    81      */
    82     private final SchemaOutputResolver schemaOutputResolver;
    84     private final ProcessingEnvironment env;
    86     /**
    87      *
    88      * @param classes
    89      *      The set of classes passed to the AnnotationProcessor
    90      * @param xmlFile
    91      *      The configuration file.
    92      * @throws SAXException
    93      *      If this is thrown, the error has already been reported.
    94      * @throws IOException
    95      *     If any IO errors occur.
    96      */
    97     public ConfigReader(ProcessingEnvironment env, Collection<? extends TypeElement> classes, File xmlFile, ErrorHandler errorHandler) throws SAXException, IOException {
    98         this.env = env;
    99         Config config = parseAndGetConfig(xmlFile, errorHandler, env.getOptions().containsKey(Options.DISABLE_XML_SECURITY));
   100         checkAllClasses(config,classes);
   101         String path =   xmlFile.getAbsolutePath();
   102         String xmlPath = path.substring(0,path.lastIndexOf(File.separatorChar));
   103         schemaOutputResolver = createSchemaOutputResolver(config,xmlPath);
   105     }
   108     /**
   109      * This creates a regular expression
   110      * for the user pattern , matches the input classes
   111      * passed by the user and returns the final
   112      * list of classes that need to be included for a config file
   113      * after applying those patterns
   114      *
   115      */
   116     public Collection<Reference> getClassesToBeIncluded() {
   117         return classesToBeIncluded;
   118     }
   120     private void checkAllClasses(Config config, Collection<? extends TypeElement> rootClasses) {
   122         List<Pattern> includeRegexList = config.getClasses().getIncludes();
   123         List<Pattern>  excludeRegexList = config.getClasses().getExcludes();
   125         OUTER:
   126         for (TypeElement typeDecl : rootClasses) {
   128             String qualifiedName = typeDecl.getQualifiedName().toString();
   130             for (Pattern pattern : excludeRegexList) {
   131                 boolean match = checkPatternMatch(qualifiedName, pattern);
   132                 if (match)
   133                     continue OUTER; // excluded
   134             }
   136             for (Pattern pattern : includeRegexList) {
   137                 boolean match = checkPatternMatch(qualifiedName, pattern);
   138                 if (match) {
   139                     classesToBeIncluded.add(new Reference(typeDecl,env));
   140                     break;
   141                 }
   142             }
   143         }
   144     }
   146     /**
   147      * This returns the SchemaOutputResolver to generate the schemas
   148      */
   149     public SchemaOutputResolver getSchemaOutputResolver(){
   150         return schemaOutputResolver;
   151     }
   153     private SchemaOutputResolver createSchemaOutputResolver(Config config, String xmlpath) {
   154         File baseDir = new File(xmlpath, config.getBaseDir().getPath());
   155         SchemaOutputResolverImpl outResolver = new SchemaOutputResolverImpl (baseDir);
   157         for( Schema schema : (List<Schema>)config.getSchema() ) {
   158             String namespace = schema.getNamespace();
   159             File location = schema.getLocation();
   160             outResolver.addSchemaInfo(namespace,location);
   161         }
   162         return outResolver;
   163     }
   165     /**
   166      * This will  check if the qualified name matches the pattern
   167      *
   168      * @param qualifiedName
   169      *      The qualified name of the TypeDeclaration
   170      * @param pattern
   171      *       The  pattern obtained from the users input
   172      *
   173      */
   174     private boolean checkPatternMatch(String qualifiedName, Pattern pattern) {
   175         Matcher matcher = pattern.matcher(qualifiedName);
   176         return matcher.matches();
   177     }
   181     /**
   182      * Lazily parsed schema for the binding file.
   183      */
   184     private static SchemaCache configSchema = new SchemaCache(Config.class.getResource("config.xsd"));
   187     /**
   188      * Parses an xml config file and returns a Config object.
   189      *
   190      * @param xmlFile
   191      *        The xml config file which is passed by the user to annotation processing
   192      * @return
   193      *        A non null Config object
   194      */
   195     private Config parseAndGetConfig (File xmlFile, ErrorHandler errorHandler, boolean disableSecureProcessing) throws SAXException, IOException {
   196         XMLReader reader;
   197         try {
   198             SAXParserFactory factory = XmlFactory.createParserFactory(disableSecureProcessing);
   199             reader = factory.newSAXParser().getXMLReader();
   200         } catch (ParserConfigurationException e) {
   201             // in practice this will never happen
   202             throw new Error(e);
   203         }
   204         NGCCRuntimeEx runtime = new NGCCRuntimeEx(errorHandler);
   206         // set up validator
   207         ValidatorHandler validator = configSchema.newValidator();
   208         validator.setErrorHandler(errorHandler);
   210         // the validator will receive events first, then the parser.
   211         reader.setContentHandler(new ForkContentHandler(validator,runtime));
   213         reader.setErrorHandler(errorHandler);
   214         Config config = new Config(runtime);
   215         runtime.setRootHandler(config);
   216         reader.parse(new InputSource(xmlFile.toURL().toExternalForm()));
   217         runtime.reset();
   219         return config;
   220     }
   221     /**
   222      * Controls where the JAXB RI puts the generates
   223      * schema files.
   224      * @author
   225      *     Bhakti Mehta (bhakti.mehta@sun.com)
   226      */
   227     private static final class SchemaOutputResolverImpl extends SchemaOutputResolver{
   229         /**
   230          * Directory to which we put the rest of the files.
   231          * Never be null.
   232          */
   233         private final File baseDir;
   235         /**
   236          * Namespace URI to the location of the schema.
   237          * This captures what the user specifies.
   238          */
   239         private final Map<String,File> schemas = new HashMap<String,File>();
   242         /**
   243          * Decides where the schema file (of the given namespace URI)
   244          * will be written, and return it as a {@link Result} object.
   245          *
   246          */
   247         public Result createOutput( String namespaceUri, String suggestedFileName ) {
   249             // the user's preference takes a precedence
   250             if(schemas.containsKey(namespaceUri)) {
   251                 File loc = schemas.get(namespaceUri);
   252                 if(loc==null)   return null;    // specifically not to generate a schema
   254                 // create directories if necessary. we've already checked that the baseDir
   255                 // exists, so this should be no surprise to users.
   256                 loc.getParentFile().mkdirs();
   258                 return new StreamResult(loc);   // generate into a file the user specified.
   259             }
   261             // if the user didn't say anything about this namespace,
   262             // generate it into the default directory with a default name.
   264              File schemaFile = new File (baseDir, suggestedFileName);
   265              // The systemId for the result will be schemaFile
   266              return new StreamResult(schemaFile);
   267         }
   270         public SchemaOutputResolverImpl(File baseDir) {
   271             assert baseDir!=null;
   272             this.baseDir = baseDir;
   273         }
   275         public void addSchemaInfo(String namespaceUri, File location) {
   276             if (namespaceUri == null )
   277                 //generate elements in no namespace
   278                 namespaceUri = "";
   279             schemas.put(namespaceUri, location);
   281         }
   283     }
   284 }

mercurial