001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: ClassMetadata.java,v 1.11.2.2 2008/01/07 15:14:20 cwl Exp $
007: */
008:
009: package com.sleepycat.persist.model;
010:
011: import java.io.Serializable;
012: import java.util.List;
013: import java.util.Map;
014:
015: /**
016: * The metadata for a persistent class. A persistent class may be specified
017: * with the {@link Entity} or {@link Persistent} annotation.
018: *
019: * <p>{@code ClassMetadata} objects are thread-safe. Multiple threads may
020: * safely call the methods of a shared {@code ClassMetadata} object.</p>
021: *
022: * <p>This and other metadata classes are classes rather than interfaces to
023: * allow adding properties to the model at a future date without causing
024: * incompatibilities. Any such property will be given a default value and
025: * its use will be optional.</p>
026: *
027: * @author Mark Hayes
028: */
029: public class ClassMetadata implements Serializable {
030:
031: private static final long serialVersionUID = -2520207423701776679L;
032:
033: private String className;
034: private int version;
035: private String proxiedClassName;
036: private boolean entityClass;
037: private PrimaryKeyMetadata primaryKey;
038: private Map<String, SecondaryKeyMetadata> secondaryKeys;
039: private List<FieldMetadata> compositeKeyFields;
040:
041: /**
042: * Used by an {@code EntityModel} to construct persistent class metadata.
043: */
044: public ClassMetadata(String className, int version,
045: String proxiedClassName, boolean entityClass,
046: PrimaryKeyMetadata primaryKey,
047: Map<String, SecondaryKeyMetadata> secondaryKeys,
048: List<FieldMetadata> compositeKeyFields) {
049: this .className = className;
050: this .version = version;
051: this .proxiedClassName = proxiedClassName;
052: this .entityClass = entityClass;
053: this .primaryKey = primaryKey;
054: this .secondaryKeys = secondaryKeys;
055: this .compositeKeyFields = compositeKeyFields;
056: }
057:
058: /**
059: * Returns the name of the persistent class.
060: */
061: public String getClassName() {
062: return className;
063: }
064:
065: /**
066: * Returns the version of this persistent class. This may be specified
067: * using the {@link Entity#version} or {@link Persistent#version}
068: * annotation.
069: */
070: public int getVersion() {
071: return version;
072: }
073:
074: /**
075: * Returns the class name of the proxied class if this class is a {@link
076: * PersistentProxy}, or null otherwise.
077: */
078: public String getProxiedClassName() {
079: return proxiedClassName;
080: }
081:
082: /**
083: * Returns whether this class is an entity class.
084: */
085: public boolean isEntityClass() {
086: return entityClass;
087: }
088:
089: /**
090: * Returns the primary key metadata for a key declared in this class, or
091: * null if none is declared. This may be specified using the {@link
092: * PrimaryKey} annotation.
093: */
094: public PrimaryKeyMetadata getPrimaryKey() {
095: return primaryKey;
096: }
097:
098: /**
099: * Returns an unmodifiable map of field name to secondary key metadata for
100: * all secondary keys declared in this class, or null if no secondary keys
101: * are declared in this class. This metadata may be specified using {@link
102: * SecondaryKey} annotations.
103: */
104: public Map<String, SecondaryKeyMetadata> getSecondaryKeys() {
105: return secondaryKeys;
106: }
107:
108: /**
109: * Returns an unmodifiable list of metadata for the fields making up a
110: * composite key, or null if this is a not a composite key class. The
111: * order of the fields in the returned list determines their stored order
112: * and may be specified using the {@link KeyField} annotation. When the
113: * composite key class does not implement {@link Comparable}, the order of
114: * the fields is the relative sort order.
115: */
116: public List<FieldMetadata> getCompositeKeyFields() {
117: return compositeKeyFields;
118: }
119:
120: @Override
121: public boolean equals(Object other) {
122: if (other instanceof ClassMetadata) {
123: ClassMetadata o = (ClassMetadata) other;
124: return version == o.version
125: && entityClass == o.entityClass
126: && nullOrEqual(className, o.className)
127: && nullOrEqual(proxiedClassName, o.proxiedClassName)
128: && nullOrEqual(primaryKey, o.primaryKey)
129: && nullOrEqual(secondaryKeys, o.secondaryKeys)
130: && nullOrEqual(compositeKeyFields,
131: o.compositeKeyFields);
132: } else {
133: return false;
134: }
135: }
136:
137: @Override
138: public int hashCode() {
139: return version + (entityClass ? 1 : 0) + hashCode(className)
140: + hashCode(proxiedClassName) + hashCode(primaryKey)
141: + hashCode(secondaryKeys)
142: + hashCode(compositeKeyFields);
143: }
144:
145: static boolean nullOrEqual(Object o1, Object o2) {
146: if (o1 == null) {
147: return o2 == null;
148: } else {
149: return o1.equals(o2);
150: }
151: }
152:
153: static int hashCode(Object o) {
154: if (o != null) {
155: return o.hashCode();
156: } else {
157: return 0;
158: }
159: }
160: }
|