001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: /**
021: *
022: */package org.netbeans.modules.bpel.model.impl.references;
023:
024: import java.util.Collection;
025: import java.util.LinkedList;
026:
027: import org.netbeans.modules.bpel.model.api.BpelEntity;
028: import org.netbeans.modules.bpel.model.api.BpelModel;
029: import org.netbeans.modules.bpel.model.api.Import;
030: import org.netbeans.modules.bpel.model.api.references.SchemaReference;
031: import org.netbeans.modules.bpel.model.api.support.ExNamespaceContext;
032: import org.netbeans.modules.bpel.model.impl.Utils;
033: import org.netbeans.modules.bpel.model.xam.spi.ExternalModelRetriever;
034: import org.netbeans.modules.xml.schema.model.GlobalComplexType;
035: import org.netbeans.modules.xml.schema.model.GlobalElement;
036: import org.netbeans.modules.xml.schema.model.GlobalSimpleType;
037: import org.netbeans.modules.xml.schema.model.GlobalType;
038: import org.netbeans.modules.xml.schema.model.ReferenceableSchemaComponent;
039: import org.netbeans.modules.xml.schema.model.SchemaModel;
040: import org.netbeans.modules.xml.schema.model.SchemaModelFactory;
041: import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
042: import org.netbeans.modules.xml.xam.dom.Attribute;
043: import org.openide.util.Lookup;
044: import org.openide.util.Lookup.Result;
045:
046: /**
047: * @author ads
048: *
049: */
050: public final class SchemaReferenceBuilder {
051:
052: private SchemaReferenceBuilder() {
053: Result result = Lookup.getDefault().lookup(
054: new Lookup.Template(ExternalModelRetriever.class));
055: myRetrievers = result.allInstances();
056:
057: myCollection = new LinkedList<SchemaReferenceFactory>();
058: myCollection.add(new SchemaElementFactory());
059: myCollection.add(new SchemaTypeFactory());
060: }
061:
062: public static SchemaReferenceBuilder getInstance() {
063: return INSTANCE;
064: }
065:
066: public <T extends ReferenceableSchemaComponent> SchemaReference<T> build(
067: Class<T> clazz, AbstractDocumentComponent entity,
068: Attribute attr) {
069: SchemaReference<T> ref = build(clazz, entity, entity
070: .getAttribute(attr));
071: if (ref instanceof MappedReference) {
072: ((MappedReference) ref).setAttribute(attr);
073: }
074: return ref;
075: }
076:
077: public <T extends ReferenceableSchemaComponent> SchemaReference<T> build(
078: Class<T> clazz, AbstractDocumentComponent entity,
079: String refString) {
080: if (refString == null) {
081: return null;
082: }
083: for (SchemaReferenceFactory resolver : myCollection) {
084: if (resolver.isApplicable(clazz)) {
085: return resolver.createUnresolvedReference(clazz,
086: entity, refString);
087: }
088: }
089: return null;
090: }
091:
092: public <T extends ReferenceableSchemaComponent> SchemaReference<T> build(
093: T target, Class<T> clazz, AbstractDocumentComponent entity) {
094: for (SchemaReferenceFactory resolver : myCollection) {
095: if (resolver.isApplicable(clazz)) {
096: return resolver.create(target, clazz, entity);
097: }
098: }
099: return null;
100: }
101:
102: public BpelAttributesType.AttrType getAttributeType(Attribute attr) {
103: /*Class clazz = null;
104: if ( List.class.isAssignableFrom( attr.getType() )){
105: clazz = attr.getMemberType();
106: }
107: else {
108: clazz = attr.getType();
109: }
110: for (SchemaReferenceFactory resolver : myCollection) {
111: if ( resolver.isApplicable( clazz )){
112: return resolver.getAttributeType();
113: }
114: }*/
115: return BpelAttributesType.AttrType.QNAME;
116: }
117:
118: public void setAttribute(SchemaReference ref, Attribute attr) {
119: if (ref instanceof MappedReference) {
120: ((MappedReference) ref).setAttribute(attr);
121: }
122: }
123:
124: public static Collection<SchemaModel> getSchemaModels(
125: AbstractDocumentComponent entity, String prefix) {
126: assert entity instanceof BpelEntity;
127: ExNamespaceContext context = ((BpelEntity) entity)
128: .getNamespaceContext();
129: String nsUri = context.getNamespaceURI(prefix);
130: Collection<SchemaModel> collection = null;
131:
132: /*
133: * Fix due Nikita request. For xsd primitive types we need to
134: * use preexisted primitive model.
135: */
136: if (Import.SCHEMA_IMPORT_TYPE.equals(nsUri)) {
137: collection = new LinkedList<SchemaModel>();
138: collection.add(SchemaModelFactory.getDefault()
139: .getPrimitiveTypesModel());
140: }
141: Collection<SchemaModel> moreModels = getSchemaModels(
142: ((BpelEntity) entity).getBpelModel(), nsUri);
143: if (collection == null) {
144: collection = moreModels;
145: } else {
146: collection.addAll(moreModels);
147: }
148: return collection;
149: }
150:
151: public static Collection<SchemaModel> getSchemaModels(
152: BpelModel model, String namespace) {
153: return getInstance().getModels(model, namespace);
154: }
155:
156: private Collection<SchemaModel> getModels(BpelModel model,
157: String namespace) {
158: Collection<SchemaModel> ret = new LinkedList<SchemaModel>();
159: if (myRetrievers.size() == 1) {
160: return ((ExternalModelRetriever) myRetrievers.iterator()
161: .next()).getSchemaModels(model, namespace);
162: }
163: for (Object obj : myRetrievers) {
164: ExternalModelRetriever retriever = (ExternalModelRetriever) obj;
165: Collection<SchemaModel> collection = retriever
166: .getSchemaModels(model, namespace);
167: ret.addAll(collection);
168: }
169: return ret;
170: }
171:
172: interface SchemaResolver {
173: <T extends ReferenceableSchemaComponent> T resolve(
174: AbstractNamedComponentReference<T> reference);
175: }
176:
177: private static final SchemaReferenceBuilder INSTANCE = new SchemaReferenceBuilder();
178:
179: private static Collection myRetrievers;
180:
181: private Collection<SchemaReferenceFactory> myCollection;
182: }
183:
184: interface SchemaReferenceFactory extends
185: SchemaReferenceBuilder.SchemaResolver {
186:
187: <T extends ReferenceableSchemaComponent> boolean isApplicable(
188: Class<T> clazz);
189:
190: <T extends ReferenceableSchemaComponent> SchemaReference<T> create(
191: T target, Class<T> clazz, AbstractDocumentComponent entity);
192:
193: <T extends ReferenceableSchemaComponent> SchemaReference<T> createUnresolvedReference(
194: Class<T> clazz, AbstractDocumentComponent entity,
195: String refString);
196:
197: <T extends ReferenceableSchemaComponent> SchemaReference<T> create(
198: T target, Class<T> clazz, AbstractDocumentComponent entity,
199: String refString);
200: }
201:
202: abstract class AbstractSchemaReferenceFactory implements
203: SchemaReferenceFactory {
204:
205: /* (non-Javadoc)
206: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#create(T, java.lang.Class, AbstractDocumentComponent, java.lang.String)
207: */
208: public <T extends ReferenceableSchemaComponent> SchemaReference<T> create(
209: T target, Class<T> clazz, AbstractDocumentComponent entity,
210: String refString) {
211: return create(target, clazz, entity);
212: }
213:
214: /* (non-Javadoc)
215: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#create(T, java.lang.Class, AbstractDocumentComponent)
216: */
217: public <T extends ReferenceableSchemaComponent> SchemaReference<T> create(
218: T target, Class<T> clazz, AbstractDocumentComponent entity) {
219: return new SchemaReferenceImpl<T>(target, clazz, entity, this );
220: }
221:
222: /* (non-Javadoc)
223: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#createUnresolvedReference(java.lang.Class, org.netbeans.modules.xml.xam.AbstractDocumentComponent, java.lang.String)
224: */
225: public <T extends ReferenceableSchemaComponent> SchemaReference<T> createUnresolvedReference(
226: Class<T> clazz, AbstractDocumentComponent entity,
227: String refString) {
228: return new SchemaReferenceImpl<T>(clazz, entity, refString,
229: this );
230: }
231:
232: }
233:
234: class SchemaElementFactory extends AbstractSchemaReferenceFactory {
235:
236: /* (non-Javadoc)
237: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#isApplicable(java.lang.Class)
238: */
239: public <T extends ReferenceableSchemaComponent> boolean isApplicable(
240: Class<T> clazz) {
241: return GlobalElement.class.isAssignableFrom(clazz);
242: }
243:
244: /* (non-Javadoc)
245: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#resolve(java.lang.Class, org.netbeans.modules.xml.xam.AbstractDocumentComponent, java.lang.String)
246: */
247: public <T extends ReferenceableSchemaComponent> T resolve(
248: AbstractNamedComponentReference<T> reference) {
249: AbstractDocumentComponent entity = (AbstractDocumentComponent) reference
250: .getParent();
251: String refString = reference.getRefString();
252: Class<T> clazz = reference.getType();
253:
254: String[] splited = new String[2];
255: Utils.splitQName(refString, splited);
256: Collection<SchemaModel> collection = SchemaReferenceBuilder
257: .getSchemaModels(entity, splited[0]);
258: for (SchemaModel model : collection) {
259: Collection<GlobalElement> elements = model.getSchema()
260: .getElements();
261: for (GlobalElement element : elements) {
262: if (splited[1].equals(element.getName())) {
263: return clazz.cast(element);
264: }
265: }
266: }
267: return null;
268: }
269:
270: }
271:
272: class SchemaTypeFactory extends AbstractSchemaReferenceFactory {
273:
274: /* (non-Javadoc)
275: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#isApplicable(java.lang.Class)
276: */
277: public <T extends ReferenceableSchemaComponent> boolean isApplicable(
278: Class<T> clazz) {
279: return GlobalType.class.isAssignableFrom(clazz);
280: }
281:
282: /* (non-Javadoc)
283: * @see org.netbeans.modules.bpel.model.impl.references.SchemaReferenceFactory#resolve(java.lang.Class, org.netbeans.modules.xml.xam.AbstractDocumentComponent, java.lang.String)
284: */
285: public <T extends ReferenceableSchemaComponent> T resolve(
286: AbstractNamedComponentReference<T> reference) {
287: AbstractDocumentComponent entity = (AbstractDocumentComponent) reference
288: .getParent();
289: String refString = reference.getRefString();
290: Class<T> clazz = reference.getType();
291:
292: String[] splited = new String[2];
293: Utils.splitQName(refString, splited);
294: Collection<SchemaModel> collection = SchemaReferenceBuilder
295: .getSchemaModels(entity, splited[0]);
296: for (SchemaModel model : collection) {
297: Collection<GlobalSimpleType> simpleTypes = model
298: .getSchema().getSimpleTypes();
299: for (GlobalSimpleType simpleType : simpleTypes) {
300: if (splited[1].equals(simpleType.getName())) {
301: return clazz.cast(simpleType);
302: }
303: }
304: Collection<GlobalComplexType> complexTypes = model
305: .getSchema().getComplexTypes();
306: for (GlobalComplexType complexType : complexTypes) {
307: if (splited[1].equals(complexType.getName())) {
308: return clazz.cast(complexType);
309: }
310: }
311: }
312: return null;
313: }
314: }
|