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

Save This Page
Home » xmlbeans-2.4.0-src » org.apache.xmlbeans.impl.config » [javadoc | source]