Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » config » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans.impl.config;
   17   
   18   import org.apache.xmlbeans.impl.xb.xmlconfig.ConfigDocument.Config;
   19   import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig;
   20   import org.apache.xmlbeans.impl.xb.xmlconfig.Nsconfig;
   21   import org.apache.xmlbeans.impl.xb.xmlconfig.Qnameconfig;
   22   import org.apache.xmlbeans.impl.xb.xmlconfig.Qnametargetenum;
   23   import org.apache.xmlbeans.impl.xb.xmlconfig.Usertypeconfig;
   24   import org.apache.xmlbeans.BindingConfig;
   25   import org.apache.xmlbeans.UserType;
   26   import org.apache.xmlbeans.XmlObject;
   27   import org.apache.xmlbeans.XmlError;
   28   import org.apache.xmlbeans.InterfaceExtension;
   29   import org.apache.xmlbeans.PrePostExtension;
   30   import org.apache.xmlbeans.impl.jam.JamClassLoader;
   31   import org.apache.xmlbeans.impl.jam.JamService;
   32   import org.apache.xmlbeans.impl.jam.JamServiceFactory;
   33   import org.apache.xmlbeans.impl.jam.JamServiceParams;
   34   import org.apache.xmlbeans.impl.schema.StscState;
   35   
   36   import javax.xml.namespace.QName;
   37   import java.io.File;
   38   import java.io.IOException;
   39   import java.util;
   40   
   41   /**
   42    * An implementation of BindingConfig
   43    */
   44   public class BindingConfigImpl extends BindingConfig
   45   {
   46       private Map _packageMap;
   47       private Map _prefixMap;
   48       private Map _suffixMap;
   49       private Map _packageMapByUriPrefix; // uri prefix -> package
   50       private Map _prefixMapByUriPrefix;  // uri prefix -> name prefix
   51       private Map _suffixMapByUriPrefix;  // uri prefix -> name suffix
   52       private Map _qnameTypeMap;
   53       private Map _qnameDocTypeMap;
   54       private Map _qnameElemMap;
   55       private Map _qnameAttMap;
   56   
   57       private List _interfaceExtensions;
   58       private List _prePostExtensions;
   59       private Map _userTypes;
   60   
   61       private BindingConfigImpl()
   62       {
   63           _packageMap = Collections.EMPTY_MAP;
   64           _prefixMap = Collections.EMPTY_MAP;
   65           _suffixMap = Collections.EMPTY_MAP;
   66           _packageMapByUriPrefix = Collections.EMPTY_MAP;
   67           _prefixMapByUriPrefix = Collections.EMPTY_MAP;
   68           _suffixMapByUriPrefix = Collections.EMPTY_MAP;
   69           _qnameTypeMap = Collections.EMPTY_MAP;
   70           _qnameDocTypeMap = Collections.EMPTY_MAP;
   71           _qnameElemMap = Collections.EMPTY_MAP;
   72           _qnameAttMap = Collections.EMPTY_MAP;
   73           _interfaceExtensions = new ArrayList();
   74           _prePostExtensions = new ArrayList();
   75           _userTypes = Collections.EMPTY_MAP;
   76       }
   77   
   78       public static BindingConfig forConfigDocuments(Config[] configs, File[] javaFiles, File[] classpath)
   79       {
   80           return new BindingConfigImpl(configs, javaFiles, classpath);
   81       }
   82   
   83       private BindingConfigImpl(Config[] configs, File[] javaFiles, File[] classpath)
   84       {
   85           _packageMap = new LinkedHashMap();
   86           _prefixMap = new LinkedHashMap();
   87           _suffixMap = new LinkedHashMap();
   88           _packageMapByUriPrefix = new LinkedHashMap();
   89           _prefixMapByUriPrefix = new LinkedHashMap();
   90           _suffixMapByUriPrefix = new LinkedHashMap();
   91           _qnameTypeMap = new LinkedHashMap();
   92           _qnameDocTypeMap = new LinkedHashMap();
   93           _qnameElemMap = new LinkedHashMap();
   94           _qnameAttMap = new LinkedHashMap();
   95           _interfaceExtensions = new ArrayList();
   96           _prePostExtensions = new ArrayList();
   97           _userTypes = new LinkedHashMap();
   98   
   99           for (int i = 0; i < configs.length; i++)
  100           {
  101               Config config = configs[i];
  102               Nsconfig[] nsa = config.getNamespaceArray();
  103               for (int j = 0; j < nsa.length; j++)
  104               {
  105                   recordNamespaceSetting(nsa[j].getUri(), nsa[j].getPackage(), _packageMap);
  106                   recordNamespaceSetting(nsa[j].getUri(), nsa[j].getPrefix(), _prefixMap);
  107                   recordNamespaceSetting(nsa[j].getUri(), nsa[j].getSuffix(), _suffixMap);
  108                   recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getPackage(), _packageMapByUriPrefix);
  109                   recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getPrefix(), _prefixMapByUriPrefix);
  110                   recordNamespacePrefixSetting(nsa[j].getUriprefix(), nsa[j].getSuffix(), _suffixMapByUriPrefix);
  111               }
  112   
  113               Qnameconfig[] qnc = config.getQnameArray();
  114               for (int j = 0; j < qnc.length; j++)
  115               {
  116                   List applyto = qnc[j].xgetTarget().xgetListValue();
  117                   QName name = qnc[j].getName();
  118                   String javaname = qnc[j].getJavaname();
  119                   for (int k = 0; k < applyto.size(); k++)
  120                   {
  121                       Qnametargetenum a = (Qnametargetenum) applyto.get(k);
  122                       switch (a.enumValue().intValue())
  123                       {
  124                       case Qnametargetenum.INT_TYPE:
  125                           _qnameTypeMap.put(name, javaname);
  126                           break;
  127                       case Qnametargetenum.INT_DOCUMENT_TYPE:
  128                           _qnameDocTypeMap.put(name, javaname);
  129                           break;
  130                       case Qnametargetenum.INT_ACCESSOR_ELEMENT:
  131                           _qnameElemMap.put(name, javaname);
  132                           break;
  133                       case Qnametargetenum.INT_ACCESSOR_ATTRIBUTE:
  134                           _qnameAttMap.put(name, javaname);
  135                           break;
  136                       }
  137                   }
  138               }
  139   
  140               Extensionconfig[] ext = config.getExtensionArray();
  141               for (int j = 0; j < ext.length; j++)
  142               {
  143                   recordExtensionSetting(javaFiles, classpath, ext[j]);
  144               }
  145               
  146               Usertypeconfig[] utypes = config.getUsertypeArray();
  147               for (int j = 0; j < utypes.length; j++)
  148               {
  149                   recordUserTypeSetting(javaFiles, classpath, utypes[j]);
  150               }
  151           }
  152   
  153           secondPhaseValidation();
  154           //todo normalize();
  155       }
  156   
  157       void addInterfaceExtension(InterfaceExtensionImpl ext)
  158       {
  159           if (ext==null)
  160               return;
  161   
  162           _interfaceExtensions.add(ext);
  163       }
  164   
  165       void addPrePostExtension(PrePostExtensionImpl ext)
  166       {
  167           if (ext==null)
  168               return;
  169   
  170           _prePostExtensions.add(ext);
  171       }
  172   
  173       void secondPhaseValidation()
  174       {
  175           // validate interface methods collisions
  176           Map methodSignatures = new HashMap();
  177   
  178           for (int i = 0; i < _interfaceExtensions.size(); i++)
  179           {
  180               InterfaceExtensionImpl interfaceExtension = (InterfaceExtensionImpl) _interfaceExtensions.get(i);
  181   
  182               InterfaceExtensionImpl.MethodSignatureImpl[] methods = (InterfaceExtensionImpl.MethodSignatureImpl[])interfaceExtension.getMethods();
  183               for (int j = 0; j < methods.length; j++)
  184               {
  185                   InterfaceExtensionImpl.MethodSignatureImpl ms = methods[j];
  186   
  187                   if (methodSignatures.containsKey(methods[j]))
  188                   {
  189   
  190                       InterfaceExtensionImpl.MethodSignatureImpl ms2 = (InterfaceExtensionImpl.MethodSignatureImpl) methodSignatures.get(methods[j]);
  191                       if (!ms.getReturnType().equals(ms2.getReturnType()))
  192                       {
  193                           BindingConfigImpl.error("Colliding methods '" + ms.getSignature() + "' in interfaces " +
  194                           ms.getInterfaceName() + " and " + ms2.getInterfaceName() + ".", null);
  195                       }
  196   
  197                       return;
  198                   }
  199   
  200                   // store it into hashmap
  201                   methodSignatures.put(methods[j], methods[j]);
  202               }
  203           }
  204   
  205           // validate that PrePostExtension-s do not intersect
  206           for (int i = 0; i < _prePostExtensions.size() - 1; i++)
  207           {
  208               PrePostExtensionImpl a = (PrePostExtensionImpl) _prePostExtensions.get(i);
  209               for (int j = 1; j < _prePostExtensions.size(); j++)
  210               {
  211                   PrePostExtensionImpl b = (PrePostExtensionImpl) _prePostExtensions.get(j);
  212                   if (a.hasNameSetIntersection(b))
  213                       BindingConfigImpl.error("The applicable domain for handler '" + a.getHandlerNameForJavaSource() +
  214                           "' intersects with the one for '" + b.getHandlerNameForJavaSource() + "'.", null);
  215               }
  216           }
  217       }
  218   
  219       private static void recordNamespaceSetting(Object key, String value, Map result)
  220       {
  221           if (value == null)
  222               return;
  223           else if (key == null)
  224               result.put("", value);
  225           else if (key instanceof String && "##any".equals(key))
  226               result.put(key, value);
  227           else if (key instanceof List)
  228           {
  229               for (Iterator i = ((List)key).iterator(); i.hasNext(); )
  230               {
  231                   String uri = (String)i.next();
  232                   if ("##local".equals(uri))
  233                       uri = "";
  234                   result.put(uri, value);
  235               }
  236           }
  237       }
  238   
  239       private static void recordNamespacePrefixSetting(List list, String value, Map result)
  240       {
  241           if (value == null)
  242               return;
  243           else if (list == null)
  244               return;
  245           for (Iterator i = list.iterator(); i.hasNext(); )
  246           {
  247               result.put(i.next(), value);
  248           }
  249       }
  250   
  251       private void recordExtensionSetting(File[] javaFiles, File[] classpath, Extensionconfig ext)
  252       {
  253           NameSet xbeanSet = null;
  254           Object key = ext.getFor();
  255   
  256   
  257           if (key instanceof String && "*".equals(key))
  258               xbeanSet = NameSet.EVERYTHING;
  259           else if (key instanceof List)
  260           {
  261               NameSetBuilder xbeanSetBuilder = new NameSetBuilder();
  262               for (Iterator i = ((List) key).iterator(); i.hasNext();)
  263               {
  264                   String xbeanName = (String) i.next();
  265                   xbeanSetBuilder.add(xbeanName);
  266               }
  267               xbeanSet = xbeanSetBuilder.toNameSet();
  268           }
  269   
  270           if (xbeanSet == null)
  271               error("Invalid value of attribute 'for' : '" + key + "'.", ext);
  272   
  273           Extensionconfig.Interface[] intfXO = ext.getInterfaceArray();
  274           Extensionconfig.PrePostSet ppXO    = ext.getPrePostSet(); 
  275   
  276           if (intfXO.length > 0 || ppXO != null)
  277           {
  278               JamClassLoader jamLoader = getJamLoader(javaFiles, classpath);
  279               for (int i = 0; i < intfXO.length; i++)
  280               {
  281                   addInterfaceExtension(InterfaceExtensionImpl.newInstance(jamLoader, xbeanSet, intfXO[i]));
  282               }
  283   
  284               addPrePostExtension(PrePostExtensionImpl.newInstance(jamLoader, xbeanSet, ppXO));
  285           }
  286       }
  287   
  288       private void recordUserTypeSetting(File[] javaFiles, File[] classpath,
  289               Usertypeconfig usertypeconfig)
  290       {
  291           JamClassLoader jamLoader = getJamLoader(javaFiles, classpath);
  292           UserTypeImpl userType = UserTypeImpl.newInstance(jamLoader, usertypeconfig);
  293           _userTypes.put(userType.getName(), userType);
  294       }
  295   
  296   
  297       private String lookup(Map map, Map mapByUriPrefix, String uri)
  298       {
  299           if (uri == null)
  300               uri = "";
  301           String result = (String)map.get(uri);
  302           if (result != null)
  303               return result;
  304           if (mapByUriPrefix != null)
  305           {
  306               result = lookupByUriPrefix(mapByUriPrefix, uri);
  307               if (result != null)
  308                   return result;
  309           }
  310   
  311           return (String)map.get("##any");
  312       }
  313   
  314       private String lookupByUriPrefix(Map mapByUriPrefix, String uri)
  315       {
  316           if (uri == null)
  317               return null;
  318           if (!mapByUriPrefix.isEmpty())
  319           {
  320               String uriprefix = null;
  321               Iterator i = mapByUriPrefix.keySet().iterator();
  322               while (i.hasNext())
  323               {
  324                   String nextprefix = (String)i.next();
  325                   if (uriprefix != null && nextprefix.length() < uriprefix.length())
  326                       continue;
  327                   if (uri.startsWith(nextprefix))
  328                       uriprefix = nextprefix;
  329               }
  330   
  331               if (uriprefix != null)
  332                   return (String)mapByUriPrefix.get(uriprefix);
  333           }
  334           return null;
  335       }
  336   
  337       //package methods
  338       static void warning(String s, XmlObject xo)
  339       {
  340           StscState.get().error(s, XmlError.SEVERITY_WARNING, xo);
  341       }
  342   
  343       static void error(String s, XmlObject xo)
  344       {
  345           StscState.get().error(s, XmlError.SEVERITY_ERROR, xo);
  346       }
  347   
  348       //public methods
  349   
  350       public String lookupPackageForNamespace(String uri)
  351       {
  352           return lookup(_packageMap, _packageMapByUriPrefix, uri);
  353       }
  354   
  355       public String lookupPrefixForNamespace(String uri)
  356       {
  357           return lookup(_prefixMap, _prefixMapByUriPrefix, uri);
  358       }
  359   
  360       public String lookupSuffixForNamespace(String uri)
  361       {
  362           return lookup(_suffixMap, _suffixMapByUriPrefix, uri);
  363       }
  364   
  365       /** @deprecated replaced with {@link #lookupJavanameForQName(QName, int)} */
  366       public String lookupJavanameForQName(QName qname)
  367       {
  368           String result = (String)_qnameTypeMap.get(qname);
  369           if (result != null)
  370               return result;
  371           return (String)_qnameDocTypeMap.get(qname);
  372       }
  373   
  374       public String lookupJavanameForQName(QName qname, int kind)
  375       {
  376           switch (kind)
  377           {
  378           case QNAME_TYPE:
  379               return (String)_qnameTypeMap.get(qname);
  380           case QNAME_DOCUMENT_TYPE:
  381               return (String)_qnameDocTypeMap.get(qname);
  382           case QNAME_ACCESSOR_ELEMENT:
  383               return (String)_qnameElemMap.get(qname);
  384           case QNAME_ACCESSOR_ATTRIBUTE:
  385               return (String)_qnameAttMap.get(qname);
  386           }
  387           return null;
  388       }
  389   
  390       public UserType lookupUserTypeForQName(QName qname)
  391       {
  392           if (qname == null)
  393               return null;
  394   
  395           return (UserType) _userTypes.get(qname);
  396       }
  397   
  398       public InterfaceExtension[] getInterfaceExtensions()
  399       {
  400           return (InterfaceExtension[])_interfaceExtensions.toArray(new InterfaceExtension[_interfaceExtensions.size()]);
  401       }
  402   
  403       public InterfaceExtension[] getInterfaceExtensions(String fullJavaName)
  404       {
  405           List result = new ArrayList();
  406           for (int i = 0; i < _interfaceExtensions.size(); i++)
  407           {
  408               InterfaceExtensionImpl intfExt = (InterfaceExtensionImpl) _interfaceExtensions.get(i);
  409               if (intfExt.contains(fullJavaName))
  410                   result.add(intfExt);
  411           }
  412   
  413           return (InterfaceExtension[])result.toArray(new InterfaceExtension[result.size()]);
  414       }
  415   
  416       public PrePostExtension[] getPrePostExtensions()
  417       {
  418           return (PrePostExtension[])_prePostExtensions.toArray(new PrePostExtension[_prePostExtensions.size()]);
  419       }
  420   
  421       public PrePostExtension getPrePostExtension(String fullJavaName)
  422       {
  423           for (int i = 0; i < _prePostExtensions.size(); i++)
  424           {
  425               PrePostExtensionImpl prePostExt = (PrePostExtensionImpl) _prePostExtensions.get(i);
  426               if (prePostExt.contains(fullJavaName))
  427                   return prePostExt;
  428           }
  429           return null;
  430       }
  431   
  432       private JamClassLoader getJamLoader(File[] javaFiles, File[] classpath)
  433       {
  434           JamServiceFactory jf = JamServiceFactory.getInstance();
  435           JamServiceParams params = jf.createServiceParams();
  436           params.set14WarningsEnabled(false);
  437           // BUGBUG(radup) This is here because the above doesn't do the trick
  438           params.setShowWarnings(false);
  439   
  440           // process the included sources
  441           if (javaFiles!=null)
  442               for (int i = 0; i < javaFiles.length; i++)
  443                   params.includeSourceFile(javaFiles[i]);
  444   
  445           //params.setVerbose(DirectoryScanner.class);
  446   
  447           // add the sourcepath and classpath, if specified
  448           params.addClassLoader(this.getClass().getClassLoader());
  449           if (classpath != null)
  450               for (int i = 0; i < classpath.length; i++)
  451                   params.addClasspath(classpath[i]);
  452   
  453           // create service, get classes, return compiler
  454           JamService service;
  455           try
  456           {
  457               service = jf.createService(params);
  458           }
  459           catch (IOException ioe)
  460           {
  461               error("Error when accessing .java files.", null);
  462               return null;
  463           }
  464   
  465   //        JClass[] cls = service.getAllClasses();
  466   //        for (int i = 0; i < cls.length; i++)
  467   //        {
  468   //            JClass cl = cls[i];
  469   //            System.out.println("CL: " + cl + " " + cl.getQualifiedName());
  470   //            JMethod[] methods = cl.getMethods();
  471   //            for (int j = 0; j < methods.length; j++)
  472   //            {
  473   //                JMethod method = methods[j];
  474   //                System.out.println("    " + method.getQualifiedName());
  475   //            }
  476   //        }
  477   
  478           return service.getClassLoader();
  479       }
  480   }

Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » config » [javadoc | source]