Source Code Cross Referenced for MetadataStandard.java in  » GIS » GeoTools-2.4.1 » org » geotools » metadata » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.metadata 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2007, GeoTools Project Managment Committee (PMC)
005:         *   
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.metadata;
017:
018:        // J2SE dependencies
019:        import java.util.HashMap;
020:        import java.util.Map;
021:        import javax.swing.tree.DefaultTreeModel;
022:        import javax.swing.tree.TreeModel;
023:
024:        // Geotools dependencies
025:        import org.geotools.resources.i18n.ErrorKeys;
026:        import org.geotools.resources.i18n.Errors;
027:
028:        /**
029:         * Enumeration of some metadata standards. A standard is defined by a set of Java interfaces
030:         * in a specific package or subpackages. For example the {@linkplain #ISO_19115 ISO 19115}
031:         * standard is defined by <A HREF="http://geoapi.sourceforge.net">GeoAPI</A> interfaces in
032:         * the {@link org.opengis.metadata} package and subpackages.
033:         * <p>
034:         * This class provides some methods operating on metadata instances through
035:         * {@linkplain java.lang.reflect Java reflection}. The following rules are
036:         * assumed:
037:         * <p>
038:         * <ul>
039:         *   <li>Properties (or metadata attributes) are defined by the set of {@code get*()}
040:         *       (arbitrary return type) or {@code is*()} (boolean return type) methods found
041:         *       in the <strong>interface</strong>. Getters declared in the implementation
042:         *       only are ignored.</li>
043:         *   <li>A property is <cite>writable</cite> if a {@code set*(...)} method is defined
044:         *       in the implementation class for the corresponding {@code get*()} method. The
045:         *       setter don't need to be defined in the interface.</li>
046:         * </ul>
047:         *
048:         * @since 2.4
049:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/metadata/MetadataStandard.java $
050:         * @version $Id: MetadataStandard.java 25175 2007-04-16 13:40:57Z desruisseaux $
051:         * @author Martin Desruisseaux (Geomatys)
052:         */
053:        public final class MetadataStandard {
054:            /**
055:             * An instance working on ISO 19115 standard as defined by
056:             * <A HREF="http://geoapi.sourceforge.net">GeoAPI</A> interfaces
057:             * in the {@link org.opengis.metadata} package and subpackages.
058:             */
059:            public static final MetadataStandard ISO_19115 = new MetadataStandard(
060:                    "org.opengis.metadata.");
061:
062:            /**
063:             * The root packages for metadata interfaces. Must ends with {@code "."}.
064:             */
065:            private final String interfacePackage;
066:
067:            /**
068:             * Accessors for the specified implementations.
069:             */
070:            private final Map/*<Class,PropertyAccessor>*/accessors = new HashMap();
071:
072:            /**
073:             * Shared pool of {@link PropertyTree} instances, once for each thread
074:             * (in order to avoid the need for thread synchronization).
075:             */
076:            private final ThreadLocal treeBuilders = new ThreadLocal() {
077:                //@Override
078:                protected Object initialValue() {
079:                    return new PropertyTree(MetadataStandard.this );
080:                }
081:            };
082:
083:            /**
084:             * Creates a new instance working on implementation of interfaces defined
085:             * in the specified package. For the ISO 19115 standard reflected by GeoAPI
086:             * interfaces, it should be the {@link org.opengis.metadata} package.
087:             *
088:             * @param interfacePackage The root package for metadata interfaces.
089:             */
090:            public MetadataStandard(String interfacePackage) {
091:                if (!interfacePackage.endsWith(".")) {
092:                    interfacePackage += '.';
093:                }
094:                this .interfacePackage = interfacePackage;
095:            }
096:
097:            /**
098:             * Returns the accessor for the specified implementation.
099:             *
100:             * @throws ClassCastException if the specified implementation class do
101:             *         not implements a metadata interface of the expected package.
102:             */
103:            private PropertyAccessor getAccessor(final Class implementation)
104:                    throws ClassCastException {
105:                final PropertyAccessor accessor = getAccessorOptional(implementation);
106:                if (accessor == null) {
107:                    throw new ClassCastException(Errors.format(
108:                            ErrorKeys.UNKNOW_TYPE_$1, implementation.getName()));
109:                }
110:                return accessor;
111:            }
112:
113:            /**
114:             * Returns the accessor for the specified implementation, or {@code null} if none.
115:             */
116:            final PropertyAccessor getAccessorOptional(
117:                    final Class implementation) {
118:                synchronized (accessors) {
119:                    PropertyAccessor accessor = (PropertyAccessor) accessors
120:                            .get(implementation);
121:                    if (accessor == null) {
122:                        Class type = getType(implementation);
123:                        if (type != null) {
124:                            accessor = new PropertyAccessor(implementation,
125:                                    type);
126:                            accessors.put(implementation, accessor);
127:                        }
128:                    }
129:                    return accessor;
130:                }
131:            }
132:
133:            /**
134:             * Returns the metadata interface implemented by the specified implementation.
135:             * Only one metadata interface can be implemented.
136:             *
137:             * @param  metadata The metadata implementation to wraps.
138:             * @param  interfacePackage The root package for metadata interfaces.
139:             * @return The single interface, or {@code null} if none where found.
140:             */
141:            private Class getType(final Class implementation) {
142:                return PropertyAccessor.getType(implementation,
143:                        interfacePackage);
144:            }
145:
146:            /**
147:             * Returns the metadata interface implemented by the specified implementation class.
148:             *
149:             * @throws ClassCastException if the specified implementation class do
150:             *         not implements a metadata interface of the expected package.
151:             *
152:             * @see AbstractMap#getInterface
153:             */
154:            public Class getInterface(final Class implementation)
155:                    throws ClassCastException {
156:                return getAccessor(implementation).type;
157:            }
158:
159:            /**
160:             * Returns a view of the specified metadata object as a {@linkplain Map map}.
161:             * The map is backed by the metadata object using Java reflection, so changes
162:             * in the underlying metadata object are immediately reflected in the map.
163:             * The keys are the property names as determined by the list of {@code get*()}
164:             * methods declared in the {@linkplain #getInterface metadata interface}.
165:             * <p>
166:             * The map supports the {@link Map#put put} operations if the underlying
167:             * metadata object contains {@link #set*(...)} methods.
168:             *
169:             * @param  metadata The metadata object to view as a map.
170:             * @return A map view over the metadata object.
171:             * @throws ClassCastException if at the metadata object don't
172:             *         implements a metadata interface of the expected package.
173:             *
174:             * @see AbstractMap#asMap
175:             */
176:            public Map asMap(final Object metadata) throws ClassCastException {
177:                return new PropertyMap(metadata, getAccessor(metadata
178:                        .getClass()));
179:            }
180:
181:            /**
182:             * Returns a view of the specified metadata as a tree. Note that while {@link TreeModel}
183:             * is defined in the {@link javax.swing.tree} package, it can be seen as a data structure
184:             * independent of Swing. It will not force class loading of Swing framework.
185:             * <p>
186:             * In current implementation, the tree is not live (i.e. changes in metadata are not
187:             * reflected in the tree). However it may be improved in a future Geotools implementation.
188:             *
189:             * @param  metadata The metadata object to formats as a string.
190:             * @return A tree representation of the specified metadata.
191:             * @throws ClassCastException if at the metadata object don't
192:             *         implements a metadata interface of the expected package.
193:             *
194:             * @see AbstractMap#asTree
195:             */
196:            public TreeModel asTree(final Object metadata)
197:                    throws ClassCastException {
198:                final PropertyTree builder = (PropertyTree) treeBuilders.get();
199:                return new DefaultTreeModel(builder.asTree(metadata), true);
200:            }
201:
202:            /**
203:             * Returns {@code true} if this metadata is modifiable. This method is not public because it
204:             * uses heuristic rules. In case of doubt, this method conservatively returns {@code true}.
205:             *
206:             * @throws ClassCastException if the specified implementation class do
207:             *         not implements a metadata interface of the expected package.
208:             *
209:             * @see AbstractMap#isModifiable
210:             */
211:            final boolean isModifiable(final Class implementation)
212:                    throws ClassCastException {
213:                return getAccessor(implementation).isModifiable();
214:            }
215:
216:            /**
217:             * Replaces every properties in the specified metadata by their
218:             * {@linkplain ModifiableMetadata#unmodifiable unmodifiable variant.
219:             *
220:             * @throws ClassCastException if the specified implementation class do
221:             *         not implements a metadata interface of the expected package.
222:             *
223:             * @see ModifiableMetadata#freeze()
224:             */
225:            final void freeze(final Object metadata) throws ClassCastException {
226:                getAccessor(metadata.getClass()).freeze(metadata);
227:            }
228:
229:            /**
230:             * Copies all metadata from source to target. The source must implements the same
231:             * metadata interface than the target.
232:             *
233:             * @param  source The metadata to copy.
234:             * @param  target The target metadata.
235:             * @param  skipNulls If {@code true}, only non-null values will be copied.
236:             * @throws ClassCastException if the source or target object don't
237:             *         implements a metadata interface of the expected package.
238:             * @throws UnmodifiableMetadataException if the target metadata is unmodifiable,
239:             *         or if at least one setter method was required but not found.
240:             *
241:             * @see AbstractMap#AbstractMap(Object)
242:             */
243:            public void shallowCopy(final Object source, final Object target,
244:                    final boolean skipNulls) throws ClassCastException,
245:                    UnmodifiableMetadataException {
246:                ensureNonNull("target", target);
247:                final PropertyAccessor accessor = getAccessor(target.getClass());
248:                if (!accessor.type.isInstance(source)) {
249:                    ensureNonNull("source", source);
250:                    throw new ClassCastException(Errors.format(
251:                            ErrorKeys.ILLEGAL_CLASS_$2, source.getClass()
252:                                    .getName(), accessor.type.getName()));
253:                }
254:                if (!accessor.shallowCopy(source, target, skipNulls)) {
255:                    throw new UnmodifiableMetadataException(Errors
256:                            .format(ErrorKeys.UNMODIFIABLE_METADATA));
257:                }
258:            }
259:
260:            /**
261:             * Compares the two specified metadata objects. The comparaison is <cite>shallow</cite>,
262:             * i.e. all metadata attributes are compared using the {@link Object#equals} method without
263:             * recursive call to this {@code shallowEquals(...)} method for child metadata.
264:             * <p>
265:             * This method can optionaly excludes null values from the comparaison. In metadata,
266:             * null value often means "don't know", so in some occasion we want to consider two
267:             * metadata as different only if an attribute value is know for sure to be different.
268:             * <p>
269:             * The first arguments must be an implementation of a metadata interface, otherwise an
270:             * exception will be thrown. The two argument do not need to be the same implementation
271:             * however.
272:             *
273:             * @param metadata1 The first metadata object to compare.
274:             * @param metadata2 The second metadata object to compare.
275:             * @param skipNulls If {@code true}, only non-null values will be compared.
276:             * @throws ClassCastException if at least one metadata object don't
277:             *         implements a metadata interface of the expected package.
278:             *
279:             * @see AbstractMetadata#equals
280:             */
281:            public boolean shallowEquals(final Object metadata1,
282:                    final Object metadata2, final boolean skipNulls)
283:                    throws ClassCastException {
284:                if (metadata1 == metadata2) {
285:                    return true;
286:                }
287:                if (metadata1 == null || metadata2 == null) {
288:                    return false;
289:                }
290:                final PropertyAccessor accessor = getAccessor(metadata1
291:                        .getClass());
292:                if (!accessor.type.equals(getType(metadata2.getClass()))) {
293:                    return false;
294:                }
295:                return accessor.shallowEquals(metadata1, metadata2, skipNulls);
296:            }
297:
298:            /**
299:             * Computes a hash code for the specified metadata. The hash code is defined as the
300:             * sum of hash code values of all non-null properties. This is the same contract than
301:             * {@link java.util.Set#hashCode} and ensure that the hash code value is insensitive
302:             * to the ordering of properties.
303:             *
304:             * @param  metadata The metadata object to compute hash code.
305:             * @return A hash code value for the specified metadata.
306:             * @throws ClassCastException if at the metadata object don't
307:             *         implements a metadata interface of the expected package.
308:             *
309:             * @see AbstractMap#hashCode
310:             */
311:            public int hashCode(final Object metadata)
312:                    throws ClassCastException {
313:                return getAccessor(metadata.getClass()).hashCode(metadata);
314:            }
315:
316:            /**
317:             * Returns a string representation of the specified metadata.
318:             *
319:             * @param  metadata The metadata object to formats as a string.
320:             * @return A string representation of the specified metadata.
321:             * @throws ClassCastException if at the metadata object don't
322:             *         implements a metadata interface of the expected package.
323:             *
324:             * @see AbstractMap#toString
325:             */
326:            public String toString(final Object metadata)
327:                    throws ClassCastException {
328:                final PropertyTree builder = (PropertyTree) treeBuilders.get();
329:                return PropertyTree.toString(builder.asTree(metadata));
330:            }
331:
332:            /**
333:             * Ensures that the specified argument is non-null.
334:             */
335:            private static void ensureNonNull(final String name,
336:                    final Object value) {
337:                if (value == null) {
338:                    throw new NullPointerException(Errors.format(
339:                            ErrorKeys.NULL_ARGUMENT_$1, name));
340:                }
341:            }
342:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.