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-2007 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: package org.netbeans.modules.sql.framework.ui.editor.property.impl;
042:
043: import java.beans.IntrospectionException;
044: import java.beans.PropertyDescriptor;
045: import java.lang.reflect.InvocationTargetException;
046: import java.lang.reflect.Method;
047: import java.util.HashMap;
048: import java.util.Stack;
049: import org.netbeans.modules.sql.framework.ui.editor.property.IElement;
050: import org.netbeans.modules.sql.framework.ui.editor.property.INode;
051: import org.netbeans.modules.sql.framework.ui.editor.property.IResource;
052: import org.netbeans.modules.sql.framework.ui.editor.property.ITemplateGroup;
053: import org.xml.sax.Attributes;
054: import org.xml.sax.SAXException;
055:
056: /**
057: * @author Ritesh Adval
058: * @version $Revision$
059: */
060: public class TemplateFactory {
061:
062: private static HashMap<String, Class> propertyTypeToClassMap = new HashMap<String, Class>();
063: private static HashMap<String, String> tagToClassMap = new HashMap<String, String>();
064: static {
065: propertyTypeToClassMap.put("string", new String().getClass());
066: propertyTypeToClassMap.put("options", new String().getClass());
067: propertyTypeToClassMap.put("object", new String().getClass());
068: propertyTypeToClassMap.put("boolean", new String().getClass());
069: }
070: static {
071: tagToClassMap
072: .put("TemplateGroup",
073: "org.netbeans.modules.sql.framework.ui.editor.property.impl.TemplateGroup");
074: tagToClassMap
075: .put("Template",
076: "org.netbeans.modules.sql.framework.ui.editor.property.impl.Template");
077: tagToClassMap
078: .put("PropertyGroup",
079: "org.netbeans.modules.sql.framework.ui.editor.property.impl.PropertyGroup");
080: tagToClassMap
081: .put(
082: "Property",
083: "org.netbeans.modules.sql.framework.ui.editor.property.impl.BasicPropertySupport");
084: tagToClassMap
085: .put(
086: "OptionProperty",
087: "org.netbeans.modules.sql.framework.ui.editor.property.impl.OptionPropertySupport");
088: tagToClassMap
089: .put("Option",
090: "org.netbeans.modules.sql.framework.ui.editor.property.impl.BasicOption");
091: }
092:
093: public static Object invokeGetter(Object bean, String propertyName)
094: throws NoSuchMethodException, InvocationTargetException,
095: IllegalAccessException, IntrospectionException {
096: return invokeGetter(bean, propertyName, null, null);
097: }
098:
099: public static Object invokeGetter(Object obj, String propertyName,
100: Class[] parameterTypes, Object[] params)
101: throws NoSuchMethodException, InvocationTargetException,
102: IllegalAccessException, IntrospectionException {
103:
104: String base = capitalize(propertyName);
105: Method readMethod;
106:
107: // Since there can be multiple setter methods but only one getter
108: // method, find the getter method first so that you know what the
109: // property type is. For booleans, there can be "is" and "get"
110: // methods. If an "is" method exists, this is the official
111: // reader method so look for this one first.
112: try {
113: readMethod = obj.getClass().getMethod("is" + base,
114: parameterTypes);
115: } catch (Exception getterExc) {
116: // no "is" method, so look for a "get" method.
117: readMethod = obj.getClass().getMethod("get" + base,
118: parameterTypes);
119: }
120:
121: return readMethod.invoke(obj, params);
122: }
123:
124: public static Object invokeSetter(Object bean, String propertyName,
125: Object val) throws NoSuchMethodException,
126: InvocationTargetException, IllegalAccessException,
127: IntrospectionException {
128: PropertyDescriptor pd = new PropertyDescriptor(propertyName,
129: bean.getClass());
130: Method method = pd.getWriteMethod();
131: return method.invoke(bean, new Object[] { val });
132: }
133:
134: public static void invokeSetters(Object obj, Attributes attrs)
135: throws NoSuchMethodException, InvocationTargetException,
136: IllegalAccessException, IntrospectionException {
137:
138: for (int i = 0; i < attrs.getLength(); i++) {
139: if (attrs.getQName(i).equals("class")) {
140: continue;
141: }
142: Class[] cls = new Class[] { String.class };
143: String base = capitalize(attrs.getQName(i));
144:
145: Method method = obj.getClass().getMethod("set" + base, cls);
146: method.invoke(obj, new Object[] { attrs.getValue(attrs
147: .getQName(i)) });
148: }
149: }
150:
151: static String capitalize(String s) {
152: if (s.length() == 0) {
153: return s;
154: }
155: char[] chars = s.toCharArray();
156: chars[0] = Character.toUpperCase(chars[0]);
157: return new String(chars);
158: }
159:
160: private IResource rManager;
161: private Stack<Object> stack = new Stack<Object>();
162: private ITemplateGroup tg;
163:
164: /** Creates a new instance of PropertyFactory */
165: public TemplateFactory(IResource resManager) {
166: this .rManager = resManager;
167: }
168:
169: public void endElement(String uri, String localName, String qName) {
170: if (stack.size() != 0) {
171: stack.pop();
172: }
173: }
174:
175: public ITemplateGroup getTemplateGroup() {
176: return tg;
177: }
178:
179: public void startElement(String uri, String localName,
180: String qName, Attributes attrs) throws SAXException {
181: try {
182: Object obj = null;
183: obj = createObject(uri, localName, qName, attrs);
184: if (qName.equals("TemplateGroup")) {
185: tg = (TemplateGroup) obj;
186: }
187:
188: if (obj != null) {
189: IElement element = (IElement) obj;
190:
191: if (stack.size() != 0) {
192: INode node = (INode) stack.peek();
193: node.add(element);
194: }
195:
196: String partialKeyName = getBundleKeyName(element);
197: // set localized values from bundle
198: if (partialKeyName != null) {
199:
200: String dName = rManager
201: .getLocalizedValue(partialKeyName
202: + "_DISPLAYNAME");
203: element.setDisplayName(dName);
204:
205: String tTip = rManager
206: .getLocalizedValue(partialKeyName
207: + "_TOOLTIP");
208: element.setToolTip(tTip);
209: }
210:
211: stack.push(obj);
212: }
213: } catch (Exception ex) {
214: ex.printStackTrace();
215: throw new SAXException(
216: "Error occured while parsing following :"
217: + "\n uri = " + uri + "\n localName = "
218: + localName + "\n qName = " + qName, ex);
219: }
220: }
221:
222: private Object createObject(String uri, String localName,
223: String qName, Attributes attrs)
224: throws NoSuchMethodException, InvocationTargetException,
225: ClassNotFoundException, InstantiationException,
226: IllegalAccessException, IntrospectionException {
227:
228: String className = attrs.getValue("class");
229: if (className == null) {
230: className = tagToClassMap.get(qName);
231: if (className == null) {
232: return null;
233: }
234: }
235:
236: Class cl = Class.forName(className);
237: Object obj = cl.newInstance();
238: invokeSetters(obj, attrs);
239: return obj;
240: }
241:
242: private String getBundleKeyName(IElement elm) {
243: if (elm == null || elm.getName() == null) {
244: return null;
245: }
246: StringBuilder strBuf = new StringBuilder(elm.getName());
247: IElement parent = elm.getParent();
248:
249: while (parent != null) {
250: String parentName = parent.getName();
251: if (parentName != null) {
252: strBuf.insert(0, parentName + "_");
253: }
254: parent = parent.getParent();
255: }
256: return strBuf.toString().toUpperCase();
257: }
258: }
|