001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2004, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.metadata.sql;
018:
019: // J2SE dependencies
020: import java.lang.reflect.InvocationHandler;
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023: import java.sql.SQLException;
024:
025: /**
026: * A metadata entity which implements (indirectly) metadata
027: * interfaces like {@link org.opengis.metadata.MetaData},
028: * {@link org.opengis.metadata.citation.Citation}, etc.
029: *
030: * Any call to a method in a metadata interface is redirected toward the
031: * {@link #invoke} method. This method use reflection in order to find
032: * the caller's method and class name. The class name is translated into
033: * a table name, and the method name is translated into a column name.
034: * Then the information is fetch in the underlying metadata database.
035: *
036: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/metadata/sql/MetadataEntity.java $
037: * @version $Id: MetadataEntity.java 20874 2006-08-07 10:00:01Z jgarnett $
038: * @author Touraïvane
039: * @author Martin Desruisseaux
040: *
041: * @since 2.1
042: */
043: final class MetadataEntity implements InvocationHandler {
044: /**
045: * The identifier used in order to locate the record for
046: * this metadata entity in the database. This is usually
047: * the primary key in the table which contains this entity.
048: */
049: private final String identifier;
050:
051: /**
052: * The connection to the database. All metadata entities
053: * created from a single database should share the same source.
054: */
055: private final MetadataSource source;
056:
057: /**
058: * Creates a new metadata entity.
059: *
060: * @param identifier The identifier used in order to locate the record for
061: * this metadata entity in the database. This is usually
062: * the primary key in the table which contains this entity.
063: * @param source The connection to the table which contains this entity.
064: */
065: public MetadataEntity(final String identifier,
066: final MetadataSource source) {
067: this .identifier = identifier;
068: this .source = source;
069: }
070:
071: /**
072: * Invoked when any method from a metadata interface is invoked.
073: *
074: * @param proxy The object on which the method is invoked.
075: * @param method The method invoked.
076: * @param args The argument given to the method.
077: */
078: public Object invoke(final Object proxy, final Method method,
079: final Object[] args) {
080: final Class type = method.getDeclaringClass();
081: if (type.getName().startsWith(source.metadataPackage)) {
082: if (args != null && args.length != 0) {
083: throw new MetadataException("Unexpected argument."); // TODO: localize
084: }
085: /*
086: * The method invoked is a method from the metadata interface.
087: * Consequently, the information should exists in the underlying
088: * database.
089: */
090: try {
091: return source.getValue(type, method, identifier);
092: } catch (SQLException e) {
093: throw new MetadataException(
094: "Failed to query the database.", e); // TODO: localize
095: }
096: } else {
097: /*
098: * The method invoked is a method inherit from a parent class,
099: * like Object.toString() or Object.hashCode(). This information
100: * is not expected to exists in the database. Forward the call
101: * to this object object, since they is only one instance by proxy.
102: * Note: do not forward to the proxy in order to avoid never-ending
103: * loop.
104: */
105: try {
106: return method.invoke(this , args);
107: } catch (IllegalAccessException e) {
108: throw new MetadataException("Illegal method call.", e); // TODO: localize
109: } catch (InvocationTargetException e) {
110: throw new MetadataException("Illegal method call.", e); // TODO: localize
111: }
112: }
113: }
114: }
|