001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.metadata.parser;
012:
013: import com.versant.core.metadata.MDStatics;
014: import com.versant.core.metadata.MDStaticUtils;
015: import com.versant.core.common.Debug;
016:
017: import java.io.PrintStream;
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: /**
023: * Class element from a .jdo file.
024: */
025: public final class JdoClass extends JdoElement implements MDStatics {
026:
027: public String name;
028: public int identityType;
029: public String objectIdClass;
030: public boolean requiresExtent;
031: public String pcSuperclass;
032: public JdoPackage parent;
033:
034: /** The field and extension elements in order or null if none. */
035: public JdoElement[] elements;
036:
037: /** The query elements or null if none. */
038: public ArrayList queries;
039: /**
040: * This can be used to override the need for a objectIdClass for appid instances
041: */
042: public boolean objectIdClasssRequired = true;
043:
044: public JdoElement getParent() {
045: return parent;
046: }
047:
048: /**
049: * Get information for this element to be used in building up a
050: * context string.
051: * @see #getContext
052: */
053: public String getSubContext() {
054: return "class[" + name + "]";
055: }
056:
057: public String toString() {
058: StringBuffer s = new StringBuffer();
059: s.append("class[");
060: s.append(name);
061: s.append("] identityType=");
062: s.append(MDStaticUtils.toIdentityTypeString(identityType));
063: s.append(" objectIdClass=");
064: s.append(objectIdClass);
065: s.append(" requiresExtent=");
066: s.append(requiresExtent);
067: s.append(" pcSuperclass=");
068: s.append(pcSuperclass);
069: return s.toString();
070: }
071:
072: public void dump() {
073: dump(Debug.OUT, "");
074: }
075:
076: public void dump(PrintStream out, String indent) {
077: out.println(indent + this );
078: if (elements != null) {
079: for (int i = 0; i < elements.length; i++) {
080: Object o = elements[i];
081: if (o instanceof JdoField) {
082: ((JdoField) o).dump(out, indent + " ");
083: } else if (o instanceof JdoExtension) {
084: ((JdoExtension) o).dump(out, indent + " ");
085: } else if (o instanceof JdoQuery) {
086: ((JdoQuery) o).dump(out, indent + " ");
087: } else {
088: out.println("unknown " + o);
089: }
090: }
091: }
092: if (queries != null) {
093: for (Iterator i = queries.iterator(); i.hasNext();) {
094: ((JdoQuery) i.next()).dump(out, indent + " ");
095: }
096: }
097: }
098:
099: /**
100: * Get the fully qualified name of this class.
101: */
102: public String getQName() {
103: return getQName(name);
104: }
105:
106: private String getQName(String n) {
107: if (n == null)
108: return null;
109: int i = n.indexOf('.');
110: if (i >= 0 || parent.name.length() == 0)
111: return n;
112: return parent.name + '.' + n;
113: }
114:
115: /**
116: * Get the fully qualified name of our PC super class or null if none.
117: */
118: public String getPCSuperClassQName() {
119: return getQName(pcSuperclass);
120: }
121:
122: /**
123: * Get the fully qualified name of our objectid-class or null if none.
124: */
125: public String getObjectIdClassQName() {
126: return getQName(objectIdClass);
127: }
128:
129: /**
130: * Does this class has a JDBC_KEY_GENERATOR set on it?
131: */
132: public boolean hasKeyGen() {
133: if (elements != null) {
134: JdoExtension ext = null;
135: for (int i = 0; i < elements.length; i++) {
136: Object o = elements[i];
137: if (o instanceof JdoExtension) {
138: ext = (JdoExtension) o;
139: if (ext.key == JdoExtension.JDBC_KEY_GENERATOR) {
140: return true;
141: } else if (ext
142: .contains(JdoExtension.JDBC_KEY_GENERATOR)) {
143: return true;
144: }
145:
146: }
147: }
148: }
149: return false;
150: }
151:
152: /**
153: * Add a JdoQuery to this class. This is called when queries declared
154: * in a separate .jdoquery resource file are moved to the main JdoClass
155: * definition and when queries are originally parsed. The q.parent field
156: * must have already been set.
157: */
158: public void addJdoQuery(JdoQuery q) {
159: // Note that this code must not change q.parent to reference this
160: // class. The parent link is used to construct parsing error messages
161: // and so must lead back to the original JdoRoot for the resource the
162: // query was declared in.
163: if (queries == null)
164: queries = new ArrayList();
165: queries.add(q);
166: }
167:
168: public int getInheritance(Map enumMap) {
169: if (elements != null) {
170: JdoExtension ext = null;
171: for (int i = 0; i < elements.length; i++) {
172: Object o = elements[i];
173: if (o instanceof JdoExtension) {
174: ext = (JdoExtension) o;
175: if (ext.key == JdoExtension.JDBC_INHERITANCE) {
176: if (ext.value == null)
177: return -1;
178: return ext.getEnum(enumMap);
179: }
180: }
181: }
182: }
183: return -1;
184: }
185:
186: public void addElement(JdoElement jdoElement) {
187: if (elements == null) {
188: elements = new JdoElement[] { jdoElement, };
189: } else {
190: JdoElement[] tmp = new JdoElement[elements.length + 1];
191: System.arraycopy(elements, 0, tmp, 0, elements.length);
192: tmp[elements.length] = jdoElement;
193: elements = tmp;
194: }
195:
196: }
197: }
|