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: package org.netbeans.modules.xslt.model.impl;
020:
021: import java.math.BigDecimal;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.LinkedList;
025: import java.util.List;
026: import java.util.StringTokenizer;
027:
028: import javax.xml.namespace.QName;
029:
030: import org.netbeans.modules.xml.xam.dom.Attribute;
031: import org.netbeans.modules.xslt.model.AttributeValueTemplate;
032: import org.netbeans.modules.xslt.model.QualifiedNameable;
033: import org.netbeans.modules.xslt.model.ReferenceableXslComponent;
034: import org.netbeans.modules.xslt.model.XslReference;
035: import org.netbeans.modules.xslt.model.enums.EnumValue;
036:
037: /**
038: * @author ads
039: *
040: */
041: class AttributeAccess {
042:
043: AttributeAccess(XslComponentImpl component) {
044: myComponent = component;
045: }
046:
047: Object getAttributeValueOf(Attribute attr, String stringValue) {
048: if (stringValue == null) {
049: return null;
050: }
051: Class clazz = attr.getType();
052: if (String.class.isAssignableFrom(clazz)) {
053: return stringValue;
054: } else {
055: for (AttributeValueFactory factory : Lazy.FACTORIES) {
056: if (factory.isApplicable(attr)) {
057: return factory.getValue(this , attr, stringValue);
058: }
059: }
060: }
061: assert false;
062: return null;
063: }
064:
065: <T extends QualifiedNameable> GlobalReferenceImpl<T> resolveGlobalReference(
066: Class<T> clazz, String value) {
067: return value == null ? null : new GlobalReferenceImpl<T>(clazz,
068: getComponent(), value);
069: }
070:
071: <T extends QualifiedNameable> List<XslReference<T>> resolveGlobalReferenceList(
072: Class<T> clazz, String value) {
073: if (value == null) {
074: return null;
075: }
076: for (ReferenceListResolveFactory factory : ReferenceListResolveFactory.Factories.FACTORIES) {
077: if (factory.isApplicable(clazz)) {
078: return factory.resolve(this , clazz, value);
079: }
080: }
081:
082: // in the case when we didn't find appropriate custom resolver
083: // we use standard resolving
084: StringTokenizer tokenizer = new StringTokenizer(value, " ");
085: List<XslReference<T>> references = new LinkedList<XslReference<T>>();
086: while (tokenizer.hasMoreTokens()) {
087: String next = tokenizer.nextToken();
088: XslReference<T> ref = resolveGlobalReference(clazz, next);
089: references.add(ref);
090: }
091: return Collections.unmodifiableList(references);
092: }
093:
094: List<QName> getQNameList(String value) {
095: if (value == null) {
096: return null;
097: }
098: StringTokenizer tokenizer = new StringTokenizer(value, " ");
099: List<QName> result = new LinkedList<QName>();
100: while (tokenizer.hasMoreTokens()) {
101: String next = tokenizer.nextToken();
102: result.add(QNameBuilder.createQName(getComponent(), next));
103: }
104: return Collections.unmodifiableList(result);
105: }
106:
107: XslComponentImpl getComponent() {
108: return myComponent;
109: }
110:
111: static class Lazy {
112:
113: static final Collection<AttributeValueFactory> FACTORIES = new LinkedList<AttributeValueFactory>();
114:
115: static {
116: FACTORIES.add(new EnumValueFactory());
117: FACTORIES.add(new DoubleValueFactory());
118: FACTORIES.add(new AttributeValueTemplateFactory());
119: FACTORIES.add(new QNameValueFactory());
120: FACTORIES.add(new BigDecimalValueFactory());
121: FACTORIES.add(new GlobalReferenceValueFactory());
122: FACTORIES.add(new ReferncesListValueFactory());
123: FACTORIES.add(new StringListValueFactory());
124: }
125: }
126:
127: private XslComponentImpl myComponent;
128: }
129:
130: interface AttributeValueFactory {
131: boolean isApplicable(Attribute attribute);
132:
133: Object getValue(AttributeAccess access, Attribute attribute,
134: String value);
135: }
136:
137: class EnumValueFactory implements AttributeValueFactory {
138:
139: @SuppressWarnings("unchecked")
140: public Object getValue(AttributeAccess access, Attribute attribute,
141: String value) {
142: Class clazz = attribute.getType();
143: Object[] objs = clazz.getEnumConstants();
144: assert clazz.isAssignableFrom(EnumValue.class);
145:
146: Object invalid = null;
147: for (Object object : objs) {
148: if (((EnumValue) object).isInvalid()) {
149: invalid = object;
150: }
151: if (value.equals(object.toString())) {
152: return object;
153: }
154: }
155: return invalid;
156: }
157:
158: public boolean isApplicable(Attribute attribute) {
159: return Enum.class.isAssignableFrom(attribute.getType());
160: }
161:
162: }
163:
164: class DoubleValueFactory implements AttributeValueFactory {
165:
166: public Object getValue(AttributeAccess access, Attribute attribute,
167: String value) {
168: return Double.parseDouble(value);
169: }
170:
171: public boolean isApplicable(Attribute attribute) {
172: return Double.class.isAssignableFrom(attribute.getType());
173: }
174:
175: }
176:
177: class AttributeValueTemplateFactory implements AttributeValueFactory {
178:
179: public Object getValue(AttributeAccess access, Attribute attribute,
180: String value) {
181: return AttributeValueTemplateImpl.creatAttributeValueTemplate(
182: access.getComponent(), value);
183: }
184:
185: public boolean isApplicable(Attribute attribute) {
186: return AttributeValueTemplate.class.isAssignableFrom(attribute
187: .getType());
188: }
189:
190: }
191:
192: class QNameValueFactory implements AttributeValueFactory {
193:
194: public Object getValue(AttributeAccess access, Attribute attribute,
195: String value) {
196: return QNameBuilder.createQName(access.getComponent(), value);
197: }
198:
199: public boolean isApplicable(Attribute attribute) {
200: return QName.class.isAssignableFrom(attribute.getType());
201: }
202:
203: }
204:
205: class BigDecimalValueFactory implements AttributeValueFactory {
206:
207: public Object getValue(AttributeAccess access, Attribute attribute,
208: String value) {
209: BigDecimal dec = null;
210: try {
211: dec = new BigDecimal(value);
212: } catch (NumberFormatException exc) {
213: // ignore this exception
214: }
215: return dec;
216: }
217:
218: public boolean isApplicable(Attribute attribute) {
219: return BigDecimal.class.isAssignableFrom(attribute.getType());
220: }
221:
222: }
223:
224: class GlobalReferenceValueFactory implements AttributeValueFactory {
225:
226: @SuppressWarnings("unchecked")
227: public Object getValue(AttributeAccess access, Attribute attribute,
228: String value) {
229: return access.resolveGlobalReference(
230: (Class<? extends QualifiedNameable>) attribute
231: .getClass(), value);
232: }
233:
234: public boolean isApplicable(Attribute attribute) {
235: return ReferenceableXslComponent.class
236: .isAssignableFrom(attribute.getType());
237: }
238:
239: }
240:
241: class ReferncesListValueFactory implements AttributeValueFactory {
242:
243: @SuppressWarnings("unchecked")
244: public Object getValue(AttributeAccess access, Attribute attribute,
245: String value) {
246: return access.resolveGlobalReferenceList(attribute
247: .getMemberType(), value);
248: }
249:
250: @SuppressWarnings("unchecked")
251: public boolean isApplicable(Attribute attribute) {
252: return List.class.isAssignableFrom(attribute.getType())
253: && attribute.getMemberType().isAssignableFrom(
254: ReferenceableXslComponent.class);
255: }
256:
257: }
258:
259: class StringListValueFactory implements AttributeValueFactory {
260:
261: public Object getValue(AttributeAccess access, Attribute attribute,
262: String value) {
263: if (value == null) {
264: return null;
265: }
266: StringTokenizer tokenizer = new StringTokenizer(value, " ");
267: List<String> ret = new LinkedList<String>();
268: while (tokenizer.hasMoreTokens()) {
269: String next = tokenizer.nextToken();
270: ret.add(next);
271: }
272: return Collections.unmodifiableList(ret);
273: }
274:
275: @SuppressWarnings("unchecked")
276: public boolean isApplicable(Attribute attribute) {
277: return List.class.isAssignableFrom(attribute.getType())
278: && attribute.getMemberType().isAssignableFrom(
279: String.class);
280: }
281:
282: }
|