001: /*
002: * LICENSE INFORMATION
003: * Copyright 2005-2007 by FZI (http://www.fzi.de).
004: * Licensed under a BSD license (http://www.opensource.org/licenses/bsd-license.php)
005: * <OWNER> = Max Völkel
006: * <ORGANIZATION> = FZI Forschungszentrum Informatik Karlsruhe, Karlsruhe, Germany
007: * <YEAR> = 2007
008: *
009: * Project information at http://semweb4j.org/rdf2go
010: */
011: package org.ontoware.rdf2go;
012:
013: import java.lang.reflect.Constructor;
014: import java.lang.reflect.InvocationTargetException;
015: import java.lang.reflect.Method;
016:
017: import org.ontoware.rdf2go.exception.ModelRuntimeException;
018: import org.slf4j.Logger;
019: import org.slf4j.LoggerFactory;
020:
021: /**
022: * Convenience class that allows registering and finding ModelFactories If you
023: * use one adaptor in your application, you should always use the default
024: * instance. If you use multiple frameworks, then you should instantiate the
025: * ModelFactory implementations directly.
026: *
027: * <h2>Usage</h2>
028: * <p>
029: * This is the main entry point to use RDF2Go, and in particular to create
030: * Models. You have to register an adaptor once to use this. Example:
031: * </p>
032: * <code>
033: * // register adapter of implementation XYZ, could be Jena or Sesame or anything.
034: * RDF2Go.register( new org.ontoware.rdf2go.impl.XYZ.ModelFactoryImpl() );
035: *
036: * // start using RDF2Go
037: * Model m = RDF2Go.getModelFactory().createModel();
038: * m.addTriple(...)
039: * </code>
040: *
041: * For each RDF2Go adapter, an ModelFactoy implementation is needed.
042: *
043: * User can call the {@link #register()} method to do that.
044: *
045: * As a fall-back, when a user calls getModelFactory() but no adapter has been
046: * registered yet, RDF2Go looks for a class named
047: * org.ontoware.rdf2go.impl.StaticBinding and tries to call a method named
048: * "getModelFactory" to get a model factory. This approach has been inspired by
049: * SL4Js static bindign approach. When multiple adapters are found, the first in
050: * the class path is used. This fall-back allows one to simply pack together a
051: * bunch of JARs an be ready to used RDF2Go without any configuration and
052: * without any OSGi.
053: *
054: * The expected class looks like this: <code><pre>
055: * package org.ontoware.rdf2go.impl;
056: *
057: * import org.ontoware.rdf2go.ModelFactory;
058: *
059: * public class StaticBinding {
060: * public static ModelFactory getModelFactory() {
061: * return new org.ontoware.rdf2go.impl.XXXX.ModelFactoryImpl();
062: * }
063: * }
064: * </pre></code>
065: *
066: * @author sauermann
067: * @author voelkel
068: */
069: public class RDF2Go {
070:
071: private static final Logger log = LoggerFactory
072: .getLogger(RDF2Go.class);
073:
074: /**
075: * the default factory for RDF2Go. This is a singleton. The field is
076: * protected by design, JUnit tests inside RDF2Go may want to reset it.
077: */
078: protected static ModelFactory modelFactory;
079:
080: private static Exception instanceRegistered;
081:
082: /**
083: * get the currently registered RDF2Go factory. Usually, you will use one
084: * adaptor in your application, register this adaptor using the .register()
085: * method and it is available here. If none is registered, this throws a
086: * RuntimeException.
087: *
088: * @return the default RDF2Go instance.
089: */
090: public static final ModelFactory getModelFactory() {
091: checkModelFactory();
092: return modelFactory;
093: }
094:
095: /**
096: * register an implementation of the RDF2Go framework. you can only register
097: * one framework inside one Java application, it will throw an Exception if
098: * you register more than one.
099: *
100: * @param modelFactory
101: * the factory to register. You can pass <code>null</code> to
102: * unregister a modelFactory. Unregistering is restricted to
103: * frameworks, you will not need it in simple applications.
104: * @throws RuntimeException
105: * if registered already. See the cause of this exception for a
106: * stacktrace where you first registered.
107: */
108: public static final void register(ModelFactory modelFactory) {
109: if (modelFactory == null) {
110: RDF2Go.modelFactory = null;
111: return;
112: }
113: if ((RDF2Go.modelFactory != null)
114: && (!RDF2Go.modelFactory.getClass().equals(
115: modelFactory.getClass())))
116: throw new RuntimeException("already registered framework "
117: + modelFactory.getClass().getName()
118: + " in the attached Exception (see stacktrace).",
119: instanceRegistered);
120: RDF2Go.modelFactory = modelFactory;
121: // store the stacktrace to help people find where the falsly registered
122: // first
123: instanceRegistered = new Exception(
124: "registered framework before");
125: }
126:
127: public static final void register(String modelFactoryClassname)
128: throws ModelRuntimeException {
129: Class<?> c;
130: try {
131: c = Class.forName(modelFactoryClassname);
132: Constructor<?> constructor;
133: try {
134: constructor = c.getConstructor(new Class[] {});
135: ModelFactory modelBuilder;
136: try {
137: modelBuilder = (ModelFactory) constructor
138: .newInstance();
139: register(modelBuilder);
140: } catch (IllegalArgumentException e) {
141: throw new ModelRuntimeException(e);
142: } catch (InstantiationException e) {
143: throw new ModelRuntimeException(e);
144: } catch (IllegalAccessException e) {
145: throw new ModelRuntimeException(e);
146: } catch (InvocationTargetException e) {
147: throw new ModelRuntimeException(e);
148: }
149: } catch (SecurityException e) {
150: throw new ModelRuntimeException(e);
151: } catch (NoSuchMethodException e) {
152: throw new ModelRuntimeException(e);
153: }
154: } catch (ClassNotFoundException e) {
155: throw new ModelRuntimeException(e);
156: }
157:
158: }
159:
160: private static void checkModelFactory() {
161: // before failing, try to find an adapter via a static binding
162: // approach, like the one used by SL4J.org
163: if (modelFactory == null) {
164: try {
165: Class<?> clazz = Class
166: .forName("org.ontoware.rdf2go.impl.StaticBinding");
167: Method method = clazz.getMethod("getModelFactory",
168: new Class[] {});
169: Object result = method.invoke(clazz, new Object[] {});
170: if (result instanceof ModelFactory) {
171: modelFactory = (ModelFactory) result;
172: log
173: .info("Using ModelFactory '"
174: + result.getClass()
175: + "' which was loaded via org.ontoware.rdf2go.impl.StaticBinding.");
176: }
177: } catch (ClassNotFoundException e) {
178: throw new ModelRuntimeException(e);
179: } catch (SecurityException e) {
180: throw new ModelRuntimeException(e);
181: } catch (NoSuchMethodException e) {
182: throw new ModelRuntimeException(e);
183: } catch (IllegalArgumentException e) {
184: throw new ModelRuntimeException(e);
185: } catch (IllegalAccessException e) {
186: throw new ModelRuntimeException(e);
187: } catch (InvocationTargetException e) {
188: throw new ModelRuntimeException(e);
189: }
190:
191: }
192:
193: // if modelfactory is still null, give up
194: if (modelFactory == null) {
195: throw new IllegalStateException(
196: "No ModelFactoy was registered. Please register one via RDF2Go.register(ModelFactory mf)");
197: }
198: }
199:
200: }
|