001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.xml.schema.model.impl;
043:
044: import java.util.ArrayList;
045: import java.util.List;
046: import java.util.Set;
047: import javax.xml.XMLConstants;
048: import org.netbeans.modules.xml.schema.model.Annotation;
049: import org.netbeans.modules.xml.schema.model.ReferenceableSchemaComponent;
050: import org.netbeans.modules.xml.schema.model.SchemaComponent;
051: import org.netbeans.modules.xml.schema.model.impl.xdm.SyncUpdateVisitor;
052: import org.netbeans.modules.xml.schema.model.visitor.SchemaVisitor;
053: import org.netbeans.modules.xml.xam.Component;
054: import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
055: import org.netbeans.modules.xml.xam.dom.Attribute;
056: import org.netbeans.modules.xml.xam.dom.DocumentComponent;
057: import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
058: import org.netbeans.modules.xml.xam.dom.DocumentModelAccess;
059: import org.w3c.dom.Element;
060: import org.w3c.dom.Node;
061: import org.w3c.dom.NodeList;
062:
063: /**
064: *
065: * @author rico
066: * @author Vidhya Narayanan
067: */
068: public abstract class SchemaComponentImpl extends
069: AbstractDocumentComponent<SchemaComponent> implements
070: SchemaComponent, DocumentModelAccess.NodeUpdater {
071:
072: public SchemaComponentImpl(SchemaModelImpl model, Element e) {
073: super (model, e);
074: }
075:
076: public SchemaModelImpl getModel() {
077: return (SchemaModelImpl) super .getModel();
078: }
079:
080: public abstract Class<? extends SchemaComponent> getComponentType();
081:
082: protected String getNamespaceURI() {
083: return XMLConstants.W3C_XML_SCHEMA_NS_URI;
084: }
085:
086: /**
087: * Leave this method as abstract
088: */
089: public abstract void accept(SchemaVisitor v);
090:
091: protected static Element createNewComponent(SchemaElements type,
092: SchemaModelImpl model) {
093: String qualified = "xsd:" + type.getName(); //NOI18N
094: return model.getDocument().createElementNS(
095: XMLConstants.W3C_XML_SCHEMA_NS_URI, qualified);
096: }
097:
098: protected void populateChildren(List<SchemaComponent> children) {
099: NodeList nl = getPeer().getChildNodes();
100: if (nl != null) {
101: for (int i = 0; i < nl.getLength(); i++) {
102: Node n = nl.item(i);
103: if (n instanceof Element) {
104: SchemaComponent comp = (SchemaComponent) getModel()
105: .getFactory().create((Element) n, this );
106: if (comp != null) {
107: children.add(comp);
108: }
109: }
110: }
111: }
112: }
113:
114: /**
115: * @return true if the elements are from the same schema model.
116: */
117: public final boolean fromSameModel(SchemaComponent other) {
118: return getModel().equals(other.getModel());
119: }
120:
121: /**
122: * Annotation always gets added as the first child.
123: */
124: public void setAnnotation(Annotation annotation) {
125: List<Class<? extends SchemaComponent>> types = new ArrayList<Class<? extends SchemaComponent>>(
126: 1);
127: types.add(SchemaComponent.class);
128: setChildBefore(Annotation.class, ANNOTATION_PROPERTY,
129: annotation, types);
130: }
131:
132: public Annotation getAnnotation() {
133: List<Annotation> annotations = getChildren(Annotation.class);
134: return annotations.isEmpty() ? null : annotations.iterator()
135: .next();
136: }
137:
138: /**
139: * Returns type of the given attribute.
140: * The type should either be:
141: * 1. String or wrappers for primitive types (Boolean, Integer,...)
142: * 2. An enum with toString() overridden to return string value by XSD specs.
143: * 3. java.util.Set
144: *
145: * @param attribute the attribute enum name
146: */
147: protected Class getAttributeType(Attribute attribute) {
148: return attribute.getType();
149: }
150:
151: /**
152: * Returns type of member in cases attribute type is collections.
153: */
154: protected Class getAttributeMemberType(Attribute attribute) {
155: return attribute.getMemberType();
156: }
157:
158: protected Object getAttributeValueOf(Attribute attr, String s) {
159: if (s == null) {
160: return null;
161: }
162: Class c = getAttributeType(attr);
163: if (String.class.isAssignableFrom(c)) {
164: return s;
165: } else if (Boolean.class.isAssignableFrom(c)) {
166: return Boolean.valueOf(s);
167: } else if (Integer.class.isAssignableFrom(c)) {
168: return Integer.valueOf(s);
169: } else if (Enum.class.isAssignableFrom(c)) {
170: Class<Enum> enumClass = (Class<Enum>) c;
171: return Util.parse(enumClass, s);
172: } else if (Set.class.isAssignableFrom(c)) {
173: return Util.valuesOf(getAttributeMemberType(attr), s);
174: }
175:
176: assert (false); // should never reached within this model implementation
177: return null;
178: }
179:
180: protected <T extends ReferenceableSchemaComponent> GlobalReferenceImpl<T> resolveGlobalReference(
181: Class<T> c, SchemaAttributes attrName) {
182: String v = getAttribute(attrName);
183: return v == null ? null
184: : new GlobalReferenceImpl<T>(c, this , v);
185: }
186:
187: protected Element checkNodeRef() {
188: Element e = (Element) getPeer();
189: if (e == null) {
190: throw new IllegalArgumentException(
191: "Valid Node reference must exist"); // NOI18N
192: }
193: return e;
194: }
195:
196: public <T extends ReferenceableSchemaComponent> NamedComponentReference<T> createReferenceTo(
197: T referenced, Class<T> type) {
198: return getModel().getFactory().createGlobalReference(
199: referenced, type, this );
200: }
201:
202: public void setId(String id) {
203: setAttribute(ID_PROPERTY, SchemaAttributes.ID, id);
204: }
205:
206: public String getId() {
207: return getAttribute(SchemaAttributes.ID);
208: }
209:
210: protected String getAttributeValue(SchemaAttributes attr) {
211: return getAttribute(attr);
212: }
213:
214: public boolean canPaste(Component child) {
215: if (!(child instanceof DocumentComponent))
216: return false;
217: return new SyncUpdateVisitor().canAdd(this ,
218: (DocumentComponent) child);
219: }
220:
221: public String lookupNamespaceURI(String prefix) {
222: return lookupNamespaceURI(prefix, true);
223: }
224: }
|