View Javadoc

1   /*
2    Copyright (C) 2007 Grid Systems, S.A.
3   
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8   
9    This library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Lesser General Public License for more details.
13  
14   You should have received a copy of the GNU Lesser General Public
15   License along with this library; if not, write to the Free Software
16   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
17  */
18  package com.gridsystems.nextgrid.api.builder;
19  
20  import java.net.URI;
21  import java.util.HashMap;
22  import java.util.LinkedHashMap;
23  import java.util.Map;
24  
25  import org.apache.commons.discovery.ResourceNameIterator;
26  import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  import com.gridsystems.nextgrid.api.pom.ref.StringReference;
31  
32  import nextgrid.api.pom.Reference;
33  
34  /**
35   * ReferenceFactory and Type Mapping manager.
36   *
37   * @author Rodrigo Ruiz
38   */
39  public final class TypeManager {
40  
41    /**
42     * Parser logger.
43     */
44    private static final Log LOG = LogFactory.getLog("PARSER");
45  
46    /**
47     * Reference Factory map.
48     */
49    private static final Map<URI, ReferenceFactory<?>> REF_FACTORIES
50      = new LinkedHashMap<URI, ReferenceFactory<?>>();
51  
52    /**
53     * XSD to Java type map.
54     */
55    private static final Map<URI, Class<?>> TYPEMAP = new HashMap<URI, Class<?>>();
56  
57    static {
58      DiscoverServiceNames dsn = new DiscoverServiceNames();
59      ResourceNameIterator it = dsn.findResourceNames(ReferenceFactory.class.getName());
60      while (it.hasNext()) {
61        String name = it.nextResourceName();
62        try {
63          if (name.indexOf(".") == -1) {
64            // Add a default package if necessary
65            name = "com.gridsystems.nextgrid.builder.ref." + name;
66          }
67          Class<?> c = Class.forName(name);
68          if (ReferenceFactory.class.isAssignableFrom(c)) {
69            ReferenceFactory<?> factory = (ReferenceFactory<?>)c.newInstance();
70            register(factory);
71          }
72        } catch (Exception e) {
73          e.printStackTrace();
74        }
75      }
76  
77      LOG.info("Registered reference factories: " + REF_FACTORIES.size());
78    }
79  
80    /**
81     * Creates a new instance.
82     */
83    private TypeManager() { }
84  
85    /**
86     * Gets the type mapped to the specified URI.
87     *
88     * @param uri XSD type URI
89     * @return A Java class
90     */
91    public static Class<?> getType(URI uri) {
92      return TYPEMAP.get(uri);
93    }
94  
95  
96    /**
97     * Creates a Reference instance for a given Java class.
98     *
99     * @param type A Java class
100    * @return An appropriate Reference instance
101    */
102   public static Reference<?> createReference(Class<?> type) {
103 //    if (Number.class.isAssignableFrom(type)) {
104 //      return new NumberReference();
105 //    } else if (DataHandler.class.isAssignableFrom(type)) {
106 //      return new DataHandlerReference();
107 //    } else {
108 //      return new StringReference();
109 //    }
110 
111     for (ReferenceFactory<?> factory : REF_FACTORIES.values()) {
112       if (factory.supports(type)) {
113         return factory.createReference(null);
114       }
115     }
116 
117     return new StringReference();
118   }
119 
120   /**
121    * Registers a reference factory with all its supported types.
122    *
123    * @param factory The instance to register
124    */
125   private static void register(ReferenceFactory<?> factory) {
126     if (factory != null) {
127       LOG.debug("Registering factory: " + factory.getClass().getName());
128       URI[] types = factory.getSupportedTypes();
129       if (types != null) {
130         int count = types.length;
131         for (int i = 0; i < count; i++) {
132           REF_FACTORIES.put(types[i], factory);
133           TYPEMAP.put(types[i], factory.toClass(types[i]));
134         }
135       }
136     }
137   }
138 
139 }