0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.uml.core.support.umlutils;
0043:
0044: import java.io.IOException;
0045: import org.netbeans.modules.uml.core.support.umlsupport.Log;
0046: import java.io.File;
0047: import java.lang.reflect.InvocationTargetException;
0048: import java.lang.reflect.Method;
0049: import java.util.StringTokenizer;
0050: import java.util.Vector;
0051: import java.util.HashMap;
0052:
0053: import org.dom4j.Attribute;
0054: import org.dom4j.Document;
0055: import org.dom4j.Node;
0056: import java.util.List;
0057:
0058: import java.util.logging.Level;
0059: import java.util.logging.Logger;
0060: import org.netbeans.modules.uml.core.metamodel.core.foundation.Element;
0061: import org.netbeans.modules.uml.core.metamodel.core.foundation.FactoryRetriever;
0062: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0063: import org.netbeans.modules.uml.core.metamodel.core.foundation.IRedefinableElement;
0064: import org.netbeans.modules.uml.core.coreapplication.ICoreProduct;
0065: import org.netbeans.modules.uml.core.generativeframework.IExpansionVariable;
0066: import org.netbeans.modules.uml.core.generativeframework.ITemplateManager;
0067: import org.netbeans.modules.uml.core.generativeframework.IVariableExpander;
0068: import org.netbeans.modules.uml.core.generativeframework.IVariableFactory;
0069: import org.netbeans.modules.uml.core.generativeframework.VariableExpander;
0070: import org.netbeans.modules.uml.core.support.umlsupport.ProductRetriever;
0071: import org.netbeans.modules.uml.core.support.umlsupport.XMLManip;
0072: import org.openide.filesystems.FileObject;
0073: import org.openide.filesystems.FileUtil;
0074:
0075: /**
0076: * <p>Title: </p>
0077: * <p>Description: </p>
0078: * <p>Copyright: Copyright (c) 2003</p>
0079: * <p>Company: </p>
0080: * @author not attributable
0081: * @version 1.0
0082: */
0083:
0084: public class PropertyElementManager implements IPropertyElementManager {
0085: private static final Logger logger = Logger
0086: .getLogger("org.netbeans.modules.uml.core");
0087: private Object m_PresentationElement = null;
0088: private Object m_ModelElement = null;
0089: private IPropertyDefinitionFactory m_PDFactory = null;
0090: private boolean m_CreateSubs = true;
0091: private String m_ElementFile = null;
0092: private IDataFormatter m_Formatter = null;
0093:
0094: public PropertyElementManager() {
0095: }
0096:
0097: public Object getPresentationElement() {
0098: return m_PresentationElement;
0099: }
0100:
0101: public void setPresentationElement(Object value) {
0102: m_PresentationElement = value;
0103: }
0104:
0105: public Object getModelElement() {
0106: return m_ModelElement;
0107: }
0108:
0109: public void setModelElement(Object value) {
0110: m_ModelElement = value;
0111: }
0112:
0113: /**
0114: * Begin the process to create a property element based on the property definition.
0115: *
0116: * @param propDef The property definition to base the building of the property element on
0117: * @param pVal The property element that has been built
0118: *
0119: * @return HRESULT
0120: *
0121: */
0122: public IPropertyElement buildTopPropertyElement(
0123: IPropertyDefinition propDef) {
0124: IPropertyElement propEle = null;
0125: if (propDef != null) {
0126: propEle = new PropertyElement();
0127: propEle.setName(propDef.getName());
0128: propEle.setPropertyDefinition(propDef);
0129: propEle.setPropertyElementManager(this );
0130: Object pDisp = getModelElement();
0131: processSubElements(pDisp, propDef, propEle);
0132: }
0133: return propEle;
0134: }
0135:
0136: public IPropertyDefinitionFactory getPDFactory() {
0137: return m_PDFactory;
0138: }
0139:
0140: public void setPDFactory(IPropertyDefinitionFactory value) {
0141: m_PDFactory = value;
0142: }
0143:
0144: /**
0145: * Determines whether or not sub elements should be created
0146: */
0147: public boolean getCreateSubs() {
0148: return m_CreateSubs;
0149: }
0150:
0151: public void setCreateSubs(boolean value) {
0152: m_CreateSubs = value;
0153: }
0154:
0155: /**
0156: * Call the given "set" method from the property definition on the passed in IDispatch using the information
0157: * from the property element.
0158: *
0159: * @param pDisp The IDispatch to call the set routine on
0160: * @param[in] pDef The property definition to process
0161: * @param[in] pEle The property element to get the information from
0162: *
0163: * @return HRESULT
0164: *
0165: */
0166: public void setData(Object pDisp1, IPropertyDefinition pDef,
0167: IPropertyElement pEle) {
0168: try {
0169: if (pEle != null && pDef != null && pDisp1 != null) {
0170: String value = pEle.getValue();
0171: String getMeth = pDef.getGetMethod();
0172: String setMeth = pDef.getSetMethod();
0173: if (setMeth != null && setMeth.length() > 0) {
0174: //get the actual element from this proxy
0175: // Object pDisp = null;
0176: // String className = getClassNameFromID(pDef);
0177: // Class clazz = Class.forName(className);
0178: // Class[] params = null;//{com.embarcadero.com.Dispatch.class};
0179: // Constructor constructor = clazz.getConstructor(params);
0180: //
0181: // Object[] paramInstances = {pDisp1};
0182: // pDisp = (IElement)constructor.newInstance(paramInstances);
0183: // before we actually do the set, we need to make sure that what we are setting
0184: // the item to is valid
0185: String str = pDef.getFromAttrMap("validate");
0186: Object obj = pEle.getElement();
0187: ICustomNameResolver resol = new CustomNameResolver();
0188: boolean valid = resol.validate(pEle,
0189: pDef.getName(), value);
0190: if (valid)
0191: resol.whenValid(pDisp1);
0192: else
0193: resol.whenInvalid(pDisp1);
0194: Class clazz1 = pDisp1.getClass();
0195: Method getmethod = clazz1.getMethod(getMeth);
0196: Method setmethod = null;
0197: Method[] meths = clazz1.getMethods();
0198: if (meths != null) {
0199: //ETSystem.out.println("Printing methods for class " + clazz1.getName());
0200: for (int i = 0; i < meths.length; i++) {
0201: if (meths[i].getName().equals(setMeth)) {
0202: setmethod = meths[i];
0203: break;
0204: }
0205: //ETSystem.out.println(meths[i].getName());
0206: }
0207: }
0208: if (setmethod != null) {
0209: Class[] types = setmethod.getParameterTypes();
0210: Object[] args = null;
0211: if (types != null && types.length > 0) {
0212: //For getting the set method I need to pass in the arguments too.
0213: //Method meth = clazz1.getMethod(setMeth, null);
0214: args = new Object[1];
0215: //need to take care of case where its one of the allowed values.
0216: String val = pEle.getValue();
0217: String validVals = pDef.getValidValues2();
0218: if (validVals != null) {
0219: StringTokenizer tokenizer = new StringTokenizer(
0220: validVals, "|");
0221: String firstToken = tokenizer
0222: .nextToken();
0223:
0224: if (validVals.startsWith("PSK")
0225: &&
0226:
0227: ((firstToken.equals("PSK_TRUE") || firstToken
0228: .equals("PSK_FALSE")))) {
0229: if ((("PSK_FALSE").equals(val))
0230: || (("0").equals(val)))
0231: args[0] = Boolean.FALSE;
0232: else if ((("PSK_TRUE").equals(val))
0233: || (("1").equals(val)))
0234: args[0] = Boolean.TRUE;
0235: }
0236: // }
0237: else {
0238: int i = 0;
0239: boolean converted = true;
0240: int convertedVal = -1;
0241: try {
0242: convertedVal = new Integer(val)
0243: .intValue();
0244: } catch (NumberFormatException e) {
0245: converted = false;
0246: }
0247: while (tokenizer.hasMoreTokens()) {
0248: if ((firstToken).equals(val)
0249: || (converted && (convertedVal == i))) {
0250: break;
0251: } else {
0252: firstToken = tokenizer
0253: .nextToken();
0254: i++;
0255: }
0256: }
0257: String enumVals = pDef
0258: .getFromAttrMap("enumValues");
0259: if (enumVals != null) {
0260: //This is a special case for setting values for enums which do not start with 0
0261: //for example diagram layout kind.
0262: StringTokenizer enumTokenizer = new StringTokenizer(
0263: enumVals, "|");
0264: int j = 0;
0265: String enumToken = "";
0266: while (enumTokenizer
0267: .hasMoreTokens()) {
0268: enumToken = enumTokenizer
0269: .nextToken();
0270: if (j == i) {
0271: try {
0272: i = (new Integer(
0273: enumToken))
0274: .intValue();
0275: break;
0276: } catch (NumberFormatException e) {
0277: }
0278: } else {
0279: j++;
0280: }
0281: }
0282: }
0283: if (!types[0].getName().equals(
0284: "java.lang.String")) {
0285: args[0] = new Integer(i);
0286: } else {
0287: args[0] = val;
0288: }
0289: }
0290: } else {
0291: args[0] = val;
0292: }
0293: }
0294: Object retObj = setmethod.invoke(pDisp1, args);
0295: if (getmethod != null) {
0296: // now that we did the set, some other process may have cancelled it, so we need
0297: // to do a get of the data and refresh the property element
0298: Object retObjGet = getmethod.invoke(pDisp1,
0299: (Object[]) null);
0300: Class returnClass = getmethod
0301: .getReturnType();
0302: if (returnClass.getName().equals(
0303: "java.lang.String")) {
0304: String str2 = (String) retObjGet;
0305: if (str2 != null && str2.length() > 0) {
0306: processResult(retObjGet, pDef, pEle);
0307: }
0308: } else {
0309: processResult(retObjGet, pDef, pEle);
0310: }
0311: pEle.setModified(false);
0312: }
0313: }
0314: }
0315: }
0316: } catch (Exception e) {
0317: // e.printStackTrace();
0318: }
0319: }
0320:
0321: /**
0322: * @param pDef
0323: * @return
0324: */
0325: private String getClassNameFromID(IPropertyDefinition pDef) {
0326: String retVal = null;
0327: if (pDef != null) {
0328: retVal = pDef.getID();
0329: if (retVal == null) {
0330: IPropertyDefinition parent = pDef.getParent();
0331: if (parent != null) {
0332: retVal = getClassNameFromID(parent);
0333: }
0334: }
0335: }
0336: return retVal;
0337: }
0338:
0339: /**
0340: * Call the given "create" method from the property definition on the passed-in IDispatch using the information
0341: * from the property element.
0342: *
0343: * @param pDisp The IDispatch to use for the method calls - if there isn't one
0344: * we will try and figure out one to use by going up the property element chain
0345: * and finding the first propEle that has a IElement stored on it, and use that
0346: * @param[in] pDef The property definition to process
0347: * @param[in] pEle The property element to get the information from
0348: *
0349: * @return HRESULT
0350: *
0351: */
0352: public Object createData(Object pDisp, IPropertyDefinition pDef,
0353: IPropertyElement pEle) {
0354: try {
0355: if (pEle != null && pDef != null) {
0356: String value = pEle.getValue();
0357: String setMeth = pDef.getCreateMethod();
0358: if (setMeth != null && setMeth.length() > 0) {
0359: // if a IDispatch hasn't been passed in, we are going to try and figure one out
0360: // we do that by going up the property element chain and finding the first one that
0361: // has a IElement on it
0362: if (pDisp == null) {
0363: Object pDisp2 = getModelElement(pEle);
0364: if (pDisp2 != null) {
0365: pDisp = pDisp2;
0366: }
0367: }
0368:
0369: if (pDisp != null) {
0370: // before we actually do the set, we need to make sure that what we are setting
0371: // the item to is valid
0372: String str = new String();
0373:
0374: Class clazz = pDisp.getClass();
0375: Method[] meths = clazz.getMethods();
0376: Method meth = null;
0377: if (meths != null) {
0378: for (int i = 0; i < meths.length; i++) {
0379: Method method = meths[i];
0380: //ETSystem.out.println("got method = " + method.toString());
0381: if (method.getName().equals(setMeth)) {
0382: meth = method;
0383: break;
0384: }
0385: }
0386: }
0387:
0388: if (meth != null) {
0389: Class[] parms = meth.getParameterTypes();
0390:
0391: Object[] args = buildParameters(parms, pEle);
0392:
0393: Object retObj = meth.invoke(pDisp, args);
0394:
0395: Class returnClass = meth.getReturnType();
0396:
0397: // some of the create methods in Wolverine are a two step process
0398: // we first create the IElement, then it needs to be added(inserted) into
0399: // its proper parent (the second s
0400: //
0401: // if the method has returned a IDispatch, then the first step has been completed,
0402: // and we need to set up the sub elements so that they can be used properly
0403: if (retObj != null) {
0404: populateSubElementsAfterCreate(pEle,
0405: retObj);
0406: } else {
0407: // some of the create methods do not return the IDispatch that was created
0408: // instead they take the IDispatch that should be created as its parameter
0409: // our BuildParameter method has handled the creation of this parameter, but
0410: // now we need to set up the subelements so that they can be used properly
0411: if (args != null && args.length > 0) {
0412: Object obj = args[0];
0413: if (obj != null) {
0414: populateSubElementsAfterCreate(
0415: pEle, obj);
0416: }
0417: }
0418: }
0419: pEle.setModified(false);
0420: }
0421: }
0422: }
0423: }
0424: } catch (Exception e) {
0425: Log.stackTrace(e);
0426: }
0427: return pDisp;
0428: }
0429:
0430: /**
0431: * Special processing after a create of an IDispatch to set the subelements up to point to that
0432: * newly created IDispatch
0433: *
0434: *
0435: * @param pEle[in] The current property element
0436: * @param pDisp[in] The newly created IDispatch
0437: *
0438: * @return HRESULT
0439: *
0440: */
0441: private void populateSubElementsAfterCreate(IPropertyElement pEle,
0442: Object obj) {
0443: pEle.setElement(obj);
0444: Vector elems = pEle.getSubElements();
0445: if (elems != null && !elems.isEmpty()) {
0446: for (int i = 0; i < elems.size(); i++) {
0447: Object elemObj = elems.get(i);
0448: if (elemObj instanceof IPropertyElement) {
0449: IPropertyElement ele = (IPropertyElement) elemObj;
0450: ele.setElement(obj);
0451: IPropertyDefinition def = ele
0452: .getPropertyDefinition();
0453: processCollectionWithSet(obj, def, ele);
0454: }
0455: }
0456: pEle.setModified(false);
0457: }
0458: }
0459:
0460: /**
0461: * Because a delete of an IElement has occurred, remove the corresponding property element from the
0462: * element structure
0463: *
0464: *
0465: * @param pDeleteEle[in] The property element that has the delete information on it
0466: * @param pEle[in] The property element that caused the delete
0467: *
0468: * @return HRESULT
0469: *
0470: */
0471: private void removeSubElementDueToDelete(
0472: IPropertyElement pDeleteEle, IPropertyElement pEle) {
0473: IPropertyElement delElem = null;
0474: if (pDeleteEle.equals(pEle))
0475: delElem = pDeleteEle.getParent();
0476: else
0477: delElem = pDeleteEle;
0478:
0479: if (delElem != null) {
0480: Vector<IPropertyElement> elems = delElem.getSubElements();
0481: if (elems != null && !elems.isEmpty()) {
0482: for (int i = elems.size() - 1; i >= 0; i--) {
0483: Object obj = elems.get(i);
0484: if (obj instanceof IPropertyElement) {
0485: IPropertyElement ele = (IPropertyElement) obj;
0486: if (ele.equals(pEle))
0487: elems.remove(i);
0488: }
0489: }
0490: delElem.setSubElements(elems);
0491: }
0492: }
0493: }
0494:
0495: private Object[] buildParameters(Class[] parms,
0496: IPropertyElement elem) {
0497: Object[] args = null;
0498: try {
0499: if (parms != null && parms.length > 0) {
0500: args = new Object[parms.length];
0501: Vector subElems = elem.getSubElements();
0502: if (subElems != null && !subElems.isEmpty()) {
0503: for (int i = 0; i < parms.length; i++) {
0504: Class parm = parms[i];
0505: String clazzName = parm.getName();
0506:
0507: //all our classes will start with packagename.I, so search for .I
0508: int pos = clazzName.indexOf(".I");
0509: if (pos >= 0) {
0510: //get the actual class name to be created
0511: String newclassName = clazzName
0512: .substring(pos + 2);
0513:
0514: //since we found a class as parameter, we need to create one.
0515: FactoryRetriever ret = FactoryRetriever
0516: .instance();
0517: Object obj = ret.createType(newclassName,
0518: null);
0519: if (obj != null
0520: && parm.isAssignableFrom(obj
0521: .getClass())) {
0522: args[i] = obj;
0523: }
0524: } else {
0525: //its a simple type, get the value from sub element and put in the args.
0526: IPropertyElement subElem = (IPropertyElement) subElems
0527: .get(i);
0528: String val = subElem.getValue();
0529: if (val == null
0530: && clazzName
0531: .equals("java.lang.String")) {
0532: args[i] = "";
0533: } else {
0534: if (val.getClass().equals(parm)) {
0535: args[i] = val;
0536: }
0537: }
0538: }
0539: }
0540: }
0541: }
0542: } catch (Exception e) {
0543:
0544: }
0545: return args;
0546: }
0547:
0548: /**
0549: * Call the given "delete" method on the passed-in delete property element using the other property
0550: * element as the parameter to the "delete".
0551: *
0552: *
0553: * @param pDeleteEle[in] The property element containing the information about the model element
0554: * that should be invoked in order to perform the delete.
0555: * @param pEle[in] The property element containing the information about the model element
0556: * that should be deleted.
0557: *
0558: * @return HRESULT
0559: *
0560: */
0561: public void deleteData(IPropertyElement pDeleteEle,
0562: IPropertyElement pEle) {
0563: try {
0564: if (pDeleteEle != null && pEle != null) {
0565: IPropertyDefinition pDef = pDeleteEle
0566: .getPropertyDefinition();
0567: if (pDef != null) {
0568: String delMeth = pDef.getDeleteMethod();
0569: Object propEle = pDeleteEle.getElement();
0570: Class clazz = propEle.getClass();
0571:
0572: //need to pass in the right set of parameters, otherwise the method will not be found.
0573: Method meth = null;//clazz.getMethod(delMeth, null);
0574: Method[] meths = clazz.getMethods();
0575: if (meths != null) {
0576: for (int i = 0; i < meths.length; i++) {
0577: Method method = meths[i];
0578: //ETSystem.out.println("got method = " + method.toString());
0579: if (method.getName().equals(delMeth)) {
0580: meth = method;
0581: break;
0582: }
0583: }
0584: }
0585:
0586: if (meth != null) {
0587: Class[] parms = meth.getParameterTypes();
0588: Object[] args = null;
0589: if (parms != null && parms.length > 0) {
0590: args = new Object[parms.length];
0591: args[0] = pEle.getElement();
0592: }
0593: meth.invoke(propEle, args);
0594: removeSubElementDueToDelete(pDeleteEle, pEle);
0595: }
0596: }
0597: }
0598: } catch (Exception e) {
0599: }
0600: }
0601:
0602: /**
0603: * Do the actual create of the property element.
0604: *
0605: * @param[in] modEle The IDispatch(model element) to get the information from
0606: * @param[in] parentDef The property definition to base the building of the property element on
0607: * @param[in] parentEle The owning property element to add the information to
0608: *
0609: * @return HRESULT
0610: *
0611: */
0612: public IPropertyElement buildElement(Object pDisp,
0613: IPropertyDefinition pDef, IPropertyElement pEle) {
0614: IPropertyElement propEle = null;
0615: try {
0616: propEle = new PropertyElement();
0617: String pdName = pDef.getName();
0618: propEle.setName(pdName);
0619: propEle.setElement(pDisp);
0620: propEle.setPropertyDefinition(pDef);
0621: propEle.setPropertyElementManager(this );
0622: if (pDisp != null) {
0623: String getStr = pDef.getGetMethod();
0624: if (getStr != null && getStr.length() > 0) {
0625: // I am really special casing this because it is 5 days before the release and the
0626: // only attribute that is not working to our knowledge is IsFinal on a Classifier.
0627: // This is because Classifier is multiply derived from RedefinableElement, but RedefEle
0628: // is not a COM object, it is just an interface. I tried writing generic code for this
0629: // and I think I have it, but it is too risky to check in at this time. So this is my
0630: // hack.
0631: // begin special case
0632: String str = pDef.getFromAttrMap("typelibQuery");
0633: String str2 = pDef.getFromAttrMap("getObject");
0634: String countStr = pDef.getFromAttrMap("getCount");
0635: if (str != null && str.length() > 0) {
0636: if (pDisp instanceof IRedefinableElement) {
0637: IRedefinableElement pRedef = (IRedefinableElement) pDisp;
0638: boolean isFinal = pRedef.getIsFinal();
0639: String buffer = "0";
0640: if (isFinal) {
0641: buffer = "1";
0642: }
0643: propEle.setValue(buffer);
0644: propEle.setOrigValue(buffer);
0645: }
0646: } else if (str2 != null && str2.length() > 0) {
0647: Object result = interpretGetObjectDefinition(propEle);
0648: if (result != null) {
0649: processResult(result, pDef, propEle);
0650: }
0651: } else {
0652: // normal processing
0653: // figure out the id of the "get" method as well as the proper type that the IDispatch should be
0654: // this will try and find the method on the IDispatch and if it is not found, it will ask the
0655: // definition if it contains an ID of a type that the IDispatch should be (because some IElements
0656: // multiply inherit, so this screws up our chain)
0657: //
0658: // the result is the ID of the method and the proper IDispatch
0659: //invoke the get method on this "name" object and then load the value and origValue.
0660: Class clazz = pDisp.getClass();
0661: try {
0662: Object result = null;
0663: IElement curE = null;
0664: java.lang.reflect.Method method = clazz
0665: .getMethod(getStr, (Class[]) null);
0666:
0667: result = method.invoke(pDisp,
0668: (Object[]) null);
0669:
0670: //now since we have the result of the method invoke, we want to process it.
0671: processResult(result, pDef, propEle);
0672:
0673: // if what we are building is the name, store the result in the parent's name field too
0674: if (pdName.equals("Name") && pEle != null) {
0675: if (result != null) {
0676: pEle.setValue(result.toString());
0677: }
0678: }
0679: } catch (NoSuchMethodException ex) {
0680: // need to check if it is our Multiplicity special case, if it is, we will continue
0681: // and process the sub elements - this will happen if the getMethod is not found on
0682: //on the class.
0683: long mult = pDef.getMultiplicity();
0684: if (mult > 1) {
0685: String setMeth = pDef.getSetMethod();
0686: if (setMeth != null
0687: && setMeth.length() > 0) {
0688: processSubElements(pDisp, pDef,
0689: propEle);
0690: }
0691: }
0692: } catch (Exception e) {
0693: e.printStackTrace();
0694: }
0695: }
0696: } else {
0697: processSubElements(pDisp, pDef, propEle);
0698: }
0699: } else {
0700: // didn't have a model element on it, but we still need to process any subs
0701: processSubElements(pDisp, pDef, propEle);
0702: }
0703: propEle.setPropertyDefinition(pDef);
0704: } catch (Exception e) {
0705: }
0706: return propEle;
0707: }
0708:
0709: /**
0710: * Method to determine how to handle the result of the invoke call
0711: *
0712: * @param[in] result The CComVariant that was returned from the invoke call
0713: * @param[in] pDef The property definition to base the building of the property element on
0714: * @param[in] pEle The property element to use
0715: *
0716: * @return HRESULT
0717: *
0718: */
0719: private void processResult(Object result, IPropertyDefinition pDef,
0720: IPropertyElement pEle) {
0721: if (result != null) {
0722: Class clazz = result.getClass();
0723: if (clazz.equals(String.class)) {
0724: pEle.setValue(result.toString());
0725: pEle.setOrigValue(result.toString());
0726: } else if (clazz.equals(Integer.class)) {
0727: pEle.setValue(result.toString());
0728: pEle.setOrigValue(result.toString());
0729: } else if (clazz.equals(Boolean.class)) {
0730: // the result was a boolean, so turn it into a string, and set the property element value to it
0731: String val = result.toString();
0732: String buffer = "";
0733: if (val.equals("true")) {
0734: buffer = "1";
0735: } else {
0736: buffer = "0";
0737: }
0738: pEle.setValue(buffer);
0739: pEle.setOrigValue(buffer);
0740: } else //if(result instanceof Dispatch)
0741: {
0742: processDispatchResult(result, pDef, pEle);
0743: }
0744: }
0745: }
0746:
0747: /**
0748: * Special processing of a IDispatch returned by the invoke call
0749: *
0750: * @param pDisp The IDispatch(model element) to get the information from
0751: * @param[in] pDef The property definition to base the building of the property element on
0752: * @param[in] pEle The property element to use
0753: *
0754: * @return HRESULT
0755: *
0756: */
0757: private void processDispatchResult(Object pDisp,
0758: IPropertyDefinition pDef, IPropertyElement pEle) {
0759: try {
0760: // if the property definition is a record (has a multiplicity > 1)
0761: // then the IDispatch that we got back is a collection
0762: long mult = pDef.getMultiplicity();
0763: if (mult > 1) {
0764: processCollectionResult(pDisp, pDef, pEle);
0765: } else {
0766: // we still got a IDispatch back, but it isn't a collection
0767: // we have stored what to do with this IDispatch in a map on the property definition
0768: // loop through them
0769: if (pDisp instanceof IElement) {
0770: IElement pModelElement = (IElement) pDisp;
0771:
0772: // find if we need to process this kind by looking at the attr map - the definition
0773: // may have had some DispatchInvoke subdefinitions that were processed as attributes
0774: // on the definition
0775: // For example, <DispatchInvoke name="{123-456}" get="Type">
0776: // This means that if the IDispatch that we just got back from the "get" call can be
0777: // cast to an object represented by the progID in name,
0778: // we want to take the IDispatch and call its Type method to get
0779: // the value to store in the property element
0780: String castID = pDef.getFromAttrMap("castID");
0781: String getStr = pDef.getFromAttrMap("castIDGet");
0782: if (getStr != null && getStr.length() > 0) {
0783: //find the method with this name on the pDisp object
0784: Method getMeth = pDisp.getClass().getMethod(
0785: getStr, (Class[]) null);
0786: if (getMeth != null) {
0787: Object result = getMeth.invoke(pDisp,
0788: (Object[]) null);
0789: if (result != null) {
0790: // process the result from the "get"
0791: processResult(result, pDef, pEle);
0792: }
0793: }
0794: } else {
0795: // we may still need to process sub elements
0796: processSubElements(pDisp, pDef, pEle);
0797: }
0798: }
0799: }
0800: } catch (Exception e) {
0801: e.printStackTrace();
0802: }
0803: }
0804:
0805: /**
0806: * Special processing of a IDispatch returned by the invoke call that is a collection
0807: *
0808: * @param pDisp The IDispatch(model element) to get the information from
0809: * @param[in] pDef The property definition to base the building of the property element on
0810: * @param[in] pEle The property element to use
0811: *
0812: * @return HRESULT
0813: *
0814: */
0815: private void processCollectionResult(Object pDisp,
0816: IPropertyDefinition pDef, IPropertyElement pEle) {
0817: try {
0818: // we are assuming that all collections have a count method on them
0819: Class clazz = pDisp.getClass();
0820: Method countMethod = clazz.getMethod("getCount",
0821: (Class[]) null);
0822:
0823: if (countMethod != null) {
0824: //invoke this count method
0825: Object countResult = countMethod.invoke(pDisp,
0826: (Object[]) null);
0827: if (countResult != null
0828: && countResult instanceof Integer) {
0829: int counter = ((Integer) countResult).intValue();
0830: if (counter > 0) {
0831: //Now I want to get the item method so that I can invoke
0832: //it on the collections object.
0833: Class[] parms = new Class[1];
0834: parms[0] = int.class;
0835: Method itemMethod = clazz.getMethod("item",
0836: parms);
0837: if (itemMethod != null) {
0838: for (int i = 0; i < counter; i++) {
0839: Object[] itemCount = new Object[1];
0840: itemCount[0] = new Integer(i);
0841: Object itemResult = itemMethod.invoke(
0842: pDisp, itemCount);
0843:
0844: if (itemResult != null) {
0845: Class itemClass = itemResult
0846: .getClass();
0847: if (itemClass.equals(String.class)) {
0848: processSubElementsAsStrings(
0849: itemResult.toString(),
0850: pDef, pEle);
0851: } else //if (itemClass.equals(Object.class))
0852: {
0853: processSubElements(itemResult,
0854: pDef, pEle);
0855: }
0856: }
0857: }
0858: }
0859: }
0860: }
0861:
0862: } else {
0863: // this collection does not have a count method on it
0864: // this is a special case, right now only applies to IMultiplicity
0865: pEle.setElement(pDisp);
0866: processSubElements(pDisp, pDef, pEle);
0867: }
0868: } catch (NoSuchMethodException exe) {
0869: //This will come if there is no getCount method on this object
0870: // this collection does not have a count method on it
0871: // this is a special case, right now only applies to IMultiplicity
0872: pEle.setElement(pDisp);
0873: processSubElements(pDisp, pDef, pEle);
0874: } catch (Exception e) {
0875: e.printStackTrace();
0876: }
0877: }
0878:
0879: /**
0880: * Process any sub elements based on sub property definitions for collections that are represented
0881: * by strings. This is a special case that is happening when the get method is called and the
0882: * result is a collection of IStrings. We go through the collection processing, but before we
0883: * were assuming objects as members of the collection. So their sub elements were being built
0884: * based on the definitions for the member objects. This case we have a string. Since there is
0885: * nothing special about the sub element, we will just build a dummy one and set its value to what
0886: * is passed in.
0887: *
0888: * @param[in] sValue The string that represents the value of the property element
0889: * @param[in] parentDef The property definition to base the building of the property element on
0890: * @param[in] parentEle The owning property element to which any subs will be added
0891: *
0892: * @return HRESULT
0893: *
0894: */
0895: private void processSubElementsAsStrings(String sValue,
0896: IPropertyDefinition parentDef, IPropertyElement parentEle) {
0897: // get the corresponding sub property definitions
0898: // still need to do this so that we have what the gui should display for it
0899: Vector<IPropertyDefinition> subDefs = parentDef
0900: .getSubDefinitions();
0901: if (subDefs != null) {
0902: // loop through to create a related property element
0903: int count = subDefs.size();
0904: for (int i = 0; i < count; i++) {
0905: IPropertyDefinition pDef = subDefs.elementAt(i);
0906:
0907: // create the property element
0908: // passing in nothing, which will just create a dummy node with no subs
0909: // which is okay for this case
0910: IPropertyElement pEle = buildElement(null, pDef,
0911: parentEle);
0912: if (pEle != null) {
0913: pEle.setValue(sValue);
0914:
0915: // insert the newly created element as a child of the current element
0916: parentEle.addSubElement(pEle);
0917: }
0918: }
0919: }
0920: }
0921:
0922: /**
0923: * Method used to figure out what to do with the passed-in IDispatch. Based on the property
0924: * definition and element, may want to do a create, or just set data.
0925: *
0926: * @param pDisp The IDispatch(model element) to process
0927: * @param[in] pDef The property definition to process
0928: * @param[in] pEle The property element to use
0929: *
0930: * @return HRESULT
0931: *
0932: */
0933: public long processData(Object pDisp, IPropertyDefinition pDef,
0934: IPropertyElement pEle) {
0935: if (pDef != null && pEle != null && pDisp != null) {
0936: String setMeth = pDef.getSetMethod();
0937: if (setMeth != null && !setMeth.equals("")) {
0938: long mult = pDef.getMultiplicity();
0939: if (mult == 1) {
0940: setData(pDisp, pDef, pEle);
0941: } else {
0942: processCollectionWithSet(pDisp, pDef, pEle);
0943: }
0944: } else {
0945: String createMeth = pDef.getCreateMethod();
0946: if (createMeth != null && !createMeth.equals("")) {
0947: createData(pDisp, pDef, pEle);
0948: } else {
0949: Vector elems = pEle.getSubElements();
0950: if (elems != null & !elems.isEmpty()) {
0951: for (int i = 0; i < elems.size(); i++) {
0952: Object elem = elems.get(i);
0953: if (elem instanceof IPropertyElement) {
0954: IPropertyElement subElem = (IPropertyElement) elems
0955: .get(i);
0956: IPropertyDefinition subDef = subElem
0957: .getPropertyDefinition();
0958: processData(pDisp, subDef, subElem);
0959: }
0960: }
0961: }
0962: }
0963: }
0964: }
0965: return 0;
0966: }
0967:
0968: /**
0969: * Special processing for property definitions that have been marked as collections but have a "set" method
0970: * eg. IMultiplicity
0971: *
0972: * @param pDisp[in] The current IDispatch
0973: * @param pDef[in] The current property definition
0974: * @param pEle[in] The current property element
0975: *
0976: * @return HRESULT
0977: *
0978: */
0979: private void processCollectionWithSet(Object pDisp,
0980: IPropertyDefinition pDef, IPropertyElement pEle) {
0981: try {
0982: String setMeth = pDef.getSetMethod();
0983: if (setMeth.length() > 0) {
0984: long mult = pDef.getMultiplicity();
0985: if (mult > 1) {
0986: String getMeth = pDef.getGetMethod();
0987: Class clazz = pDisp.getClass();
0988: Method[] meths = clazz.getMethods();
0989: Method meth = null;
0990: if (meths != null) {
0991: for (int i = 0; i < meths.length; i++) {
0992: Method method = meths[i];
0993: if (method.getName().equals(getMeth)) {
0994: meth = method;
0995: break;
0996: }
0997: }
0998: }
0999: if (meth != null) {
1000: Object obj = meth
1001: .invoke(pDisp, (Object[]) null);
1002: if (obj != null) {
1003: pEle.setElement(obj);
1004: setDispatchOfAllSubElements(pEle, obj);
1005: }
1006: }
1007: }
1008: }
1009: } catch (Exception e) {
1010: }
1011: }
1012:
1013: private void setDispatchOfAllSubElements(IPropertyElement pEle,
1014: Object obj) {
1015: try {
1016: if (pEle != null && obj != null) {
1017: String name = pEle.getName();
1018: pEle.setElement(obj);
1019: if (name.equals("Multiplicity")) {
1020: // multiplicity is a special case because the dispatch that is coming in is the element that
1021: // the multiplicity is on (attribute, parameter), but the sub elements of multiplicity and
1022: // the multiplicity object itself needs to have the IMultiplicity element on them
1023: IPropertyDefinition pDef = pEle
1024: .getPropertyDefinition();
1025: if (pDef != null) {
1026: // get the parent of this property element (will be the attribute or parameter)
1027: IPropertyElement pParent = pEle.getParent();
1028: if (pParent != null) {
1029: // get its element (attribute or parameter)
1030: Object pParentDisp = pParent.getElement();
1031: if (pParentDisp != null) {
1032: // invoke the get_Multiplicity method on the IElement
1033: String getMeth = pDef.getGetMethod();
1034: Class clazz = pParentDisp.getClass();
1035: Method[] meths = clazz.getMethods();
1036: Method meth = null;
1037: if (meths != null) {
1038: for (int i = 0; i < meths.length; i++) {
1039: Method method = meths[i];
1040: if (method.getName().equals(
1041: getMeth)) {
1042: meth = method;
1043: break;
1044: }
1045: }
1046: }
1047: if (meth != null) {
1048: Object object = meth.invoke(
1049: pParentDisp,
1050: (Object[]) null);
1051: if (object != null) {
1052: // now set the current property element's IElement to the IMultiplicity
1053: pEle.setElement(object);
1054: obj = object;
1055: }
1056: }
1057: }
1058: }
1059: }
1060: }
1061: // have the right element now as our pDisp
1062: Vector elems = pEle.getSubElements();
1063: if (elems != null && !elems.isEmpty()) {
1064: for (int i = 0; i < elems.size(); i++) {
1065: Object subObj = elems.get(i);
1066: if (subObj instanceof IPropertyElement) {
1067: IPropertyElement subElem = (IPropertyElement) subObj;
1068: setDispatchOfAllSubElements(subElem, obj);
1069: }
1070: }
1071: }
1072: }
1073: } catch (Exception e) {
1074: }
1075: }
1076:
1077: /**
1078: * Rebuild the information for the passed-in property element. This first removes all
1079: * sub elements, then rebuilds them.
1080: *
1081: *
1082: * @param modEle[in] Model element representing the element to be reloaded
1083: * @param pDef[in] Definition of the element to be reloaded
1084: * @param pEle[in] Element to be reloaded
1085: *
1086: * @return HRESULT
1087: *
1088: */
1089: public long reloadElement(Object pDisp, IPropertyDefinition pDef,
1090: IPropertyElement pEle) {
1091: if (pDisp != null && pDef != null && pEle != null) {
1092: Vector<IPropertyElement> elems = pEle.getSubElements();
1093: elems.clear();
1094: pEle.setSubElements(elems);
1095: processSubElements(pDisp, pDef, pEle);
1096:
1097: IPropertyElement parent = pEle.getParent();
1098: if (parent != null) {
1099: IPropertyElement newElement = buildElement(parent
1100: .getElement(), pDef, pEle);
1101: if (newElement != null) {
1102: interpretElementValue(newElement);
1103: pEle.setValue(newElement.getValue());
1104: }
1105: }
1106: }
1107: return 0;
1108: }
1109:
1110: /**
1111: * Rebuild the information for the passed-in property element. This first removes all
1112: * sub elements, then rebuilds only one sub element marked as a dummy node.
1113: *
1114: * This was needed for performance reasons in the property editor
1115: *
1116: *
1117: * @param modEle[in] Model element representing the element to be reloaded
1118: * @param pDef[in] Definition of the element to be reloaded
1119: * @param pEle[in] Element to be reloaded
1120: *
1121: * @return HRESULT
1122: *
1123: */
1124: public long reloadElementWithDummy(Object pDisp,
1125: IPropertyDefinition pDef, IPropertyElement pEle) {
1126: if (pDef != null && pEle != null) {
1127: Vector<IPropertyElement> elems = pEle.getSubElements();
1128: elems.clear();
1129: pEle.setSubElements(elems);
1130:
1131: pEle.setName("dummy");
1132: pEle.setPropertyDefinition(pDef);
1133: Vector defs = pDef.getSubDefinitions();
1134: if (defs != null && !defs.isEmpty()) {
1135: Object subPd = defs.get(0);
1136: if (subPd instanceof IPropertyDefinition) {
1137: IPropertyDefinition pd = (IPropertyDefinition) subPd;
1138: IPropertyElement subEle = null;
1139: if (pDisp != null)
1140: subEle = buildElement(pDisp, pd, pEle);
1141: else
1142: subEle = buildElement(m_ModelElement, pd, pEle);
1143:
1144: if (subEle != null)
1145: pEle.addSubElement(subEle);
1146: }
1147: }
1148: }
1149: return 0;
1150: }
1151:
1152: public String getElementFile() {
1153: return m_ElementFile;
1154: }
1155:
1156: public void setElementFile(String value) {
1157: m_ElementFile = value;
1158: }
1159:
1160: /**
1161: * Begin the process to create a property element based on the property definition using an already
1162: * defined file.
1163: *
1164: * @param[in] pDef The property definition to base the building of the property element on
1165: * @param[out] pVal The property elements that have been built
1166: *
1167: * @return HRESULT
1168: *
1169: */
1170: public IPropertyElement[] buildElementsUsingXMLFile(
1171: IPropertyDefinition pDef) {
1172: IPropertyElement[] pEles = null;
1173: try {
1174: //DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1175: //dbf.setNamespaceAware(true);
1176: //DocumentBuilder db = dbf.newDocumentBuilder();
1177: Document doc = XMLManip.getDOMDocument(m_ElementFile);//db.parse(new File(m_ElementFile));
1178:
1179: // file has been loaded, now find all property elements with the same name as the passed
1180: // in property definition
1181: String pDefName = pDef.getName();
1182:
1183: String pattern = "//PropertyElement[@name=\'";
1184: pattern += pDefName;
1185: pattern += "\']";
1186:
1187: List list = XMLManip.selectNodeList(doc, pattern);
1188: if (list != null && list.size() > 0) {
1189: pEles = new PropertyElement[list.size()];
1190: for (int i = 0; i < list.size(); i++) {
1191: Node node = (Node) list.get(i);
1192: IPropertyElementXML xmlElem = new PropertyElementXML();
1193: xmlElem.setName(pDefName);
1194: xmlElem.setPropertyDefinition(pDef);
1195: xmlElem.setPropertyElementManager(this );
1196:
1197: // set its information
1198: setAttributesXML(node, pDef, xmlElem);
1199:
1200: // process any sub elements
1201: processSubElementsUsingXMLFile(node, pDef, xmlElem);
1202: pEles[i] = xmlElem;
1203:
1204: }
1205: }
1206: } catch (Exception e) {
1207:
1208: }
1209: return pEles;
1210: }
1211:
1212: /**
1213: * Process any sub elements based on sub property definitions in a predetermined file
1214: *
1215: * @param[in] pNode The XML node to get the information from
1216: * @param[in] parentDef The property definition to base the building of the property element on
1217: * @param[in] parentEle The owning property element to which any subs will be added
1218: *
1219: * @return HRESULT
1220: *
1221: */
1222: private void processSubElementsUsingXMLFile(Node node,
1223: IPropertyDefinition pDef, IPropertyElement pElem) {
1224: try {
1225: /* Vector elems = pDef.getSubDefinitions();
1226: if (elems != null && !elems.isEmpty()) {
1227: for (int i = 0; i < elems.size(); i++) {
1228: Object obj = elems.get(i);
1229: if (obj instanceof IPropertyDefinition) {
1230: IPropertyDefinition def = (IPropertyDefinition) obj;
1231: String subName = def.getName();
1232: String pattern = "aElement[@name=\'";
1233: pattern += subName;
1234: pattern += "\']";
1235: List list = XPathAPI.selectNodeList(node, pattern);
1236: if (list != null && list.getLength() > 0) {
1237: for (int j = 0; j < list.getLength(); j++) {
1238: Node newNode = list.item(j);
1239: IPropertyElementXML xmlElem = buildElementUsingXMLFile(def,
1240: newNode);
1241: if (xmlElem != null) {
1242: pElem.addSubElement(xmlElem);
1243: }
1244: }
1245: }
1246: }
1247: }
1248: }*/
1249: HashMap<String, IPropertyDefinition> elems = pDef
1250: .getHashedSubDefinitions();
1251: if (elems != null
1252: && node.getNodeType() == Node.ELEMENT_NODE) {
1253: org.dom4j.Element elem = (org.dom4j.Element) node;
1254: List list = elem.selectNodes("aElement");
1255: if (list != null) {
1256: int count = list.size();
1257: for (int i = 0; i < count; i++) {
1258: Node newNode = (Node) list.get(i);
1259: if (newNode.getNodeType() == Node.ELEMENT_NODE) {
1260: org.dom4j.Element child = (org.dom4j.Element) newNode;
1261: String name = child.attributeValue("name");
1262: IPropertyDefinition def = (IPropertyDefinition) elems
1263: .get(name);
1264: IPropertyElementXML xmlElem = buildElementUsingXMLFile(
1265: def, newNode);
1266: if (xmlElem != null) {
1267: pElem.addSubElement(xmlElem);
1268: }
1269: }
1270: }
1271: }
1272: }
1273: } catch (Exception e) {
1274: }
1275: }
1276:
1277: /**
1278: * Do the actual create of the property element based on a file
1279: *
1280: * @param[in] pDef The property definition to base the building of the property element on
1281: * @param[in] pNode The xml node to get the information from
1282: * @param[out] pEle The property element that has been created
1283: *
1284: * @return HRESULT
1285: *
1286: */
1287: private IPropertyElementXML buildElementUsingXMLFile(
1288: IPropertyDefinition pDef, Node node) {
1289: IPropertyElementXML elem = new PropertyElementXML();
1290: setAttributesXML(node, pDef, elem);
1291: elem.setPropertyElementManager(this );
1292: processSubElementsUsingXMLFile(node, pDef, elem);
1293: return elem;
1294: }
1295:
1296: /**
1297: * Sets the information on the property element from the dom node in the given file
1298: *
1299: *
1300: * @param pNode[in] The DOM Node
1301: * @param pDef[in] The property definition representing the property element
1302: * @param pEle[in] The property element to have its information set
1303: *
1304: * @return HRESULT
1305: *
1306: */
1307: private void setAttributesXML(Node node, IPropertyDefinition pDef,
1308: IPropertyElement elem) {
1309: if (node != null) {
1310: if (node instanceof org.dom4j.Element) {
1311: org.dom4j.Element ele = (org.dom4j.Element) node;
1312:
1313: Attribute nameNode = ele.attribute("name");
1314: String name = "";
1315: if (nameNode != null)
1316: name = nameNode.getValue();
1317:
1318: nameNode = ele.attribute("value");
1319: String value = "";
1320: if (nameNode != null)
1321: value = nameNode.getValue();
1322:
1323: if (value.equals(""))
1324: value = pDef.getValidValues2();
1325:
1326: elem.setName(name);
1327: elem.setValue(value);
1328: elem.setOrigValue(value);
1329: elem.setPropertyDefinition(pDef);
1330: }
1331:
1332: }
1333: }
1334:
1335: /**
1336: * Sometimes the information that is stored on the property element is not what
1337: * we want to display. It may need to be interpreted, this is based on the information
1338: * on the property definition.
1339: *
1340: * @param pEle[in] The property element
1341: *
1342: * @return HRESULT
1343: *
1344: */
1345: public void interpretElementValue(IPropertyElement pEle) {
1346: if (pEle != null) {
1347: IPropertyDefinition pDef = pEle.getPropertyDefinition();
1348: String vals = pDef.getValidValues();
1349: if (vals != null && vals.length() > 0) {
1350: // if the definition has a # in it, this is our way of saying that there is
1351: // an xpath query needed to be executed in order to determine the values
1352: // of the definition
1353: int pos = vals.indexOf("#");
1354: if (pos >= 0) {
1355: // this check didn't work for the edit control, who had a list of "signs"
1356: // representing public, protected, private, so do one more check
1357: // if the definition has a # in it and it is part of a list, then we need to
1358: // evaluate the list
1359: int pos2 = vals.indexOf("|#|");
1360: if (pos2 >= 0) {
1361: processEnumeration(pEle);
1362: } else {
1363: int pos4 = vals.indexOf("#Call");
1364: if (pos4 >= 0) {
1365: processMethodCall(pEle, pDef);
1366: } else {
1367: int pos3 = vals.indexOf("");
1368: if (pos3 >= 0) {
1369: processExpansionVar(pEle);
1370: } else {
1371: // validValues2 is used to store the results of whatever was in validValues
1372: // if there is nothing in validValues2, then try to determine what should be there
1373: String val2 = pDef.getValidValues2();
1374: if (val2 == null || val2.length() == 0) {
1375: // last try to process is figure out if this is an xpath or not
1376: String cType = pDef
1377: .getControlType();
1378: if (cType != null
1379: && cType
1380: .equals("read-only"))
1381: processXPath(pEle);
1382: }
1383: }
1384: }
1385: }
1386: } else {
1387: pos = vals.indexOf("FormatString");
1388: if (pos >= 0) {
1389: processFormatString(pEle);
1390: } else {
1391: processEnumeration(pEle);
1392: }
1393: }
1394: }
1395: }
1396: }
1397:
1398: /**
1399: * The property definition states that the information to be displayed by the property element
1400: * should be a value from an xpath query. Need to figure out what the value is.
1401: *
1402: * @param[in] pEle The property element to be used
1403: *
1404: * @return HRESULT
1405: *
1406: */
1407: private void processXPath(IPropertyElement pEle) {
1408: try {
1409: IPropertyDefinition def = pEle.getPropertyDefinition();
1410: String values = def.getValidValues();
1411: if (values.length() > 0) {
1412: int pos = values.indexOf("#");
1413: if (pos >= 0) {
1414: // get the string without the "#", this is the xpath query
1415: String xpath = values.substring(pos + 1, values
1416: .length() - 1);
1417: Object obj = pEle.getElement();
1418: if (obj instanceof IElement) {
1419: IElement elem = (IElement) obj;
1420: Node node = elem.getNode();
1421: if (node != null) {
1422: Node n = XMLManip.selectSingleNode(node,
1423: xpath);
1424: if (n != null) {
1425: String str = n.getStringValue();
1426: pEle.setValue(str);
1427: pEle.setOrigValue(str);
1428: }
1429: }
1430: }
1431: }
1432: }
1433: } catch (Exception e) {
1434: }
1435: }
1436:
1437: /**
1438: * The property definition states that the information to be displayed by the property element
1439: * should be a format string. Need to figure out what the format string is.
1440: *
1441: * @param[in] pEle The property element to be used
1442: *
1443: * @return HRESULT
1444: *
1445: */
1446: private void processFormatString(IPropertyElement pElem) {
1447: if ((m_Formatter == null)
1448: && (ProductRetriever.retrieveProduct() != null)) {
1449: //m_Formatter = ProductHelper
1450: m_Formatter = ProductRetriever.retrieveProduct()
1451: .getDataFormatter();
1452: }
1453:
1454: Object obj = pElem.getElement();
1455: if (obj != null) {
1456: if (obj instanceof IElement) {
1457: IElement elem = (IElement) obj;
1458: String value = m_Formatter.formatElement(elem);
1459: pElem.setValue(value);
1460: pElem.setOrigValue(value);
1461: }
1462: }
1463: }
1464:
1465: /**
1466: * The property definition states that the information to be displayed by the property element
1467: * may be something other than what is stored on the property editor. For example, for visibility
1468: * a value of 0-3 is stored, but what we want to display is public, private, etc.
1469: *
1470: * @param[in] pEle The property element to be used
1471: *
1472: * @return HRESULT
1473: *
1474: */
1475: public void processEnumeration(IPropertyElement pElem) {
1476: String val = pElem.getValue();
1477: try {
1478: if (val != null) {
1479: Integer i = new Integer(val);
1480: IPropertyDefinition def = pElem.getPropertyDefinition();
1481: if (def != null) {
1482: String values = def.getValidValues();
1483: String enums = def.getFromAttrMap("enumValues");
1484: if (values != null && values.length() > 0) {
1485: IEnumTranslator trans = new EnumTranslator();
1486: String value = trans.translateFromEnum(i
1487: .intValue(), values, enums);
1488: pElem.setValue(value);
1489: pElem.setOrigValue(value);
1490: }
1491: }
1492: }
1493: } catch (NumberFormatException e) {
1494: //the number conversion error must have happenned.
1495: pElem.setValue(val);
1496: pElem.setOrigValue(val);
1497: /*
1498: String value = pElem.getTranslatedValue();
1499: pElem.setValue(value);
1500: pElem.setOrigValue(value);
1501: */
1502: }
1503: }
1504:
1505: /**
1506: * Call the given "insert" method from the property definition on the passed-in IDispatch using the information
1507: * from the property element.
1508: *
1509: * @param pDisp The IDispatch to use for the method calls
1510: * @param[in] pDef The property definition to process
1511: * @param[in] pEle The property element to get the information from
1512: *
1513: * @return HRESULT
1514: *
1515: */
1516: public void insertData(Object pDisp, IPropertyDefinition pDef,
1517: IPropertyElement pEle) {
1518: try {
1519: String insMeth = pDef.getInsertMethod();
1520: IPropertyDefinition tempDef = pDef;
1521: if (insMeth.length() == 0) {
1522: IPropertyElement elem = getInsertElement(pEle);
1523: if (elem != null) {
1524: IPropertyDefinition def = elem
1525: .getPropertyDefinition();
1526: if (def != null) {
1527: insMeth = def.getInsertMethod();
1528: tempDef = def;
1529: }
1530: }
1531: }
1532:
1533: if (insMeth.length() > 0) {
1534: // if a IDispatch hasn't been passed in, we are going to try and figure one out
1535: // we do that by going up the property element chain and finding the first one that
1536: // has a IElement on it
1537: if (pDisp == null) {
1538: Object newDisp = getModelElement(pEle);
1539: if (newDisp != null)
1540: pDisp = newDisp;
1541: }
1542: if (pDisp != null) {
1543: Class clazz = pDisp.getClass();
1544: Method[] meths = clazz.getMethods();
1545: Method meth = null;
1546: if (meths != null) {
1547: for (int i = 0; i < meths.length; i++) {
1548: Method method = meths[i];
1549: if (method.getName().equals(insMeth)) {
1550: meth = method;
1551: break;
1552: }
1553: }
1554: }
1555:
1556: if (meth != null) {
1557: Class[] parms = meth.getParameterTypes();
1558: Object[] args = new Object[parms.length];//buildParameters(parms, pEle);
1559: args[0] = pEle.getElement();
1560: Object obj = meth.invoke(pDisp, args);
1561: pEle.setModified(false);
1562: }
1563: }
1564: }
1565: } catch (Exception e) {
1566: }
1567: }
1568:
1569: /**
1570: * Method to navigate up the property element chain to retrieve the first model element in the chain
1571: *
1572: * @param[in] pEle The property element in which to get the model element
1573: * @param[out] pModEle The model element
1574: *
1575: * @return HRESULT
1576: *
1577: */
1578: private Object getModelElement(IPropertyElement pEle) {
1579: Object obj = pEle.getElement();
1580: if (obj == null) {
1581: IPropertyElement elem = pEle.getParent();
1582: if (elem != null) {
1583: obj = getModelElement(elem);
1584: }
1585: }
1586: return obj;
1587: }
1588:
1589: /**
1590: * Method to navigate up the property element chain to retrieve the property element that represents
1591: * the one that should be inserted into (the one with an insert method)
1592: *
1593: * @param[in] pEle The property element in which to get the insert element that it belongs to
1594: * @param[out] pInsertEle The property element that is the element in which to perform the insert
1595: *
1596: * @return HRESULT
1597: *
1598: */
1599: private IPropertyElement getInsertElement(IPropertyElement pEle) {
1600: IPropertyElement elem = null;
1601: IPropertyDefinition def = pEle.getPropertyDefinition();
1602: if (def != null) {
1603: String insMeth = def.getInsertMethod();
1604: if (insMeth.length() == 0) {
1605: IPropertyElement parElem = pEle.getParent();
1606: if (parElem != null) {
1607: elem = getInsertElement(parElem);
1608: }
1609: } else
1610: elem = pEle;
1611: }
1612: return elem;
1613: }
1614:
1615: /**
1616: * Builds and returns an empty element structure based on the passed-in definition.
1617: *
1618: * @param[in] pDef The property definition to base the building of the property element on
1619: * @param[out] pNewEle The newly created empty property element
1620: *
1621: * @return HRESULT
1622: *
1623: */
1624: public IPropertyElementXML buildEmptyElementXML(
1625: IPropertyDefinition pDef) {
1626: IPropertyElementXML propEle = new PropertyElementXML();
1627: propEle.setName(pDef.getName());
1628: propEle.setPropertyDefinition(pDef);
1629: processEmptySubElementsXML(pDef, propEle);
1630: return propEle;
1631: }
1632:
1633: /**
1634: * Process any sub elements based on sub property definitions, creating them empty
1635: *
1636: * @param[in] parentDef The property definition to base the building of the property element on
1637: * @param[in] parentEle The owning property element to which any subs will be added
1638: *
1639: * @return HRESULT
1640: *
1641: */
1642: private void processEmptySubElementsXML(IPropertyDefinition pDef,
1643: IPropertyElement pEle) {
1644: Vector elems = pDef.getSubDefinitions();
1645: if (elems != null && !elems.isEmpty()) {
1646: for (int i = 0; i < elems.size(); i++) {
1647: Object obj = elems.get(i);
1648: if (obj instanceof IPropertyDefinition) {
1649: IPropertyDefinition def = (IPropertyDefinition) obj;
1650: IPropertyElement elem = buildEmptyElementXML(def);
1651: if (elem != null)
1652: pEle.addSubElement(elem);
1653: }
1654: }
1655: }
1656: }
1657:
1658: /**
1659: * Save the passed in property elements to the given file.
1660: *
1661: * @param file[in] The file to save the elements to
1662: * @param dtdFile[in] The dtd file to use to validate the element
1663: * @param pEles[in] The elements to save
1664: *
1665: * @return HRESULT
1666: */
1667: public void saveElementsToXMLFile(String file, String dtdFile,
1668: IPropertyElement[] pEles) {
1669: Document doc = getDOMDocumentForFile(file, dtdFile);
1670: if (doc != null) {
1671: if (pEles != null && pEles.length > 0) {
1672: for (int i = 0; i < pEles.length; i++) {
1673: IPropertyElement elem = pEles[i];
1674: if (elem != null) {
1675: if (elem instanceof IPropertyElementXML) {
1676: IPropertyElementXML xmlElem = (IPropertyElementXML) elem;
1677: xmlElem.save(doc);
1678: }
1679: saveSubElementsToXMLFile(doc, elem);
1680: }
1681: }
1682: }
1683: //save the document to xml file here.
1684: }
1685: }
1686:
1687: private void saveSubElementsToXMLFile(Document doc,
1688: IPropertyElement ele) {
1689: Vector elems = ele.getSubElements();
1690: if (elems != null && !elems.isEmpty()) {
1691: for (int i = 0; i < elems.size(); i++) {
1692: Object obj = elems.get(i);
1693: if (obj instanceof IPropertyElementXML) {
1694: IPropertyElementXML elem = (IPropertyElementXML) obj;
1695: elem.save(doc);
1696: }
1697: if (obj instanceof IPropertyElement) {
1698: IPropertyElement elem = (IPropertyElement) obj;
1699: saveSubElementsToXMLFile(doc, elem);
1700: }
1701: }
1702: }
1703: }
1704:
1705: /**
1706: * Get a DOM Document for the passed-in file.
1707: *
1708: *
1709: * @param file[in] The file that needs to be queried
1710: * @param pDoc[out] The returned DOM document
1711: *
1712: * @return HRESULT
1713: *
1714: */
1715: private Document getDOMDocumentForFile(String fileName,
1716: String dtdFile) {
1717: Document doc = null;
1718:
1719: File file = new File(fileName);
1720: FileObject fo = FileUtil.toFileObject(file);
1721:
1722: if (fo != null && fo.canWrite()) {
1723: doc = XMLManip.getDOMDocument(fileName);//db.parse(file);
1724: } else {
1725: try {
1726: fo = FileUtil.createData(file);
1727: doc = XMLManip.getDOMDocument(); //db.newDocument();
1728: } catch (IOException ex) {
1729: String mesg = ex.getMessage();
1730: logger.log(Level.WARNING, mesg != null ? mesg : "", ex);
1731: }
1732: }
1733: return doc;
1734: }
1735:
1736: /**
1737: * Process any sub elements based on sub property definitions
1738: *
1739: * @param[in] modEle The IDispatch(model element) to get the information from
1740: * @param[in] parentDef The property definition to base the building of the property element on
1741: * @param[in] parentEle The owning property element to which any subs will be added
1742: *
1743: * @return HRESULT
1744: *
1745: */
1746: private void processSubElements(Object modEle,
1747: IPropertyDefinition parentDef, IPropertyElement parentEle) {
1748: if (getCreateSubs()) {
1749: Vector defs = parentDef.getSubDefinitions();
1750: if (defs != null && !defs.isEmpty()) {
1751: for (int i = 0; i < defs.size(); i++) {
1752: Object obj = defs.elementAt(i);
1753: if (obj instanceof IPropertyDefinition) {
1754: IPropertyDefinition def = (IPropertyDefinition) obj;
1755: IPropertyElement propEle = buildElement(modEle,
1756: def, parentEle);
1757: if (propEle != null)
1758: parentEle.addSubElement(propEle);
1759: }
1760: }
1761: }
1762: }
1763: }
1764:
1765: public Object interpretGetObjectDefinition(IPropertyElement pEle) {
1766: Object retVal = null;
1767: if (pEle != null) {
1768: IPropertyDefinition pDef = pEle.getPropertyDefinition();
1769: if (pDef != null) {
1770: String getObjStr = pDef.getFromAttrMap("getObject");
1771: if (getObjStr != null && getObjStr.length() > 0) {
1772: String getMethod = pDef.getGetMethod();
1773: if (getMethod != null && getMethod.length() > 0) {
1774: String getParams = pDef
1775: .getFromAttrMap("getParameters");
1776: if ((getObjStr.length() > 0)
1777: && (getMethod.length() > 0)) {
1778: // the definition has an object and a method stored in it that needs to be
1779: // created and then invoked in order to have the value
1780: // turn into a class id
1781: try {
1782: Object actual = retrieveObject(getObjStr);
1783: if (actual != null) {
1784: Class clazz = actual.getClass();
1785: // the get method may not actually be a get_X, so try invoking a method with this name
1786: // that is just a method.
1787: // but first we will try and figure out the parameters needed by the method
1788: if (getParams != null
1789: && getParams.length() > 0) {
1790: // invoke the method on this class
1791: Class[] params = new Class[1];
1792: params[0] = IElement.class;
1793: java.lang.reflect.Method method = clazz
1794: .getMethod(getMethod,
1795: params);
1796: // right now only going to figure out one, but someday we should parse this
1797: // string for delimiters
1798: Object pDispOnEle = pEle
1799: .getElement();
1800: Object[] args = new Object[1];
1801: args[0] = pDispOnEle;
1802: retVal = method.invoke(actual,
1803: args);
1804: } else {
1805: // invoke the method on this class
1806: java.lang.reflect.Method method = clazz
1807: .getMethod(getMethod,
1808: (Class[]) null);
1809:
1810: retVal = method.invoke(actual,
1811: (Object[]) null);
1812: }
1813: }
1814: } catch (NoSuchMethodException ex) {
1815: int i = 0;
1816: } catch (Exception e) {
1817: int i = 0;
1818: }
1819:
1820: }
1821: }
1822: }
1823: }
1824: }
1825: return retVal;
1826: }
1827:
1828: protected Object retrieveObject(String objName)
1829: throws ClassNotFoundException, InstantiationException,
1830: IllegalAccessException {
1831: Object retVal = null;
1832:
1833: ICoreProduct product = ProductRetriever.retrieveProduct();
1834: if (product != null) {
1835: Class clazz = Class.forName(objName);
1836: retVal = clazz.newInstance();
1837: }
1838:
1839: return retVal;
1840: }
1841:
1842: private void processMethodCall(IPropertyElement pEle,
1843: IPropertyDefinition pDef) {
1844: if (pEle != null) {
1845: String values = pDef.getValidValues();
1846: if (values != null && values.length() > 0) {
1847: // has it been tagged as an xpath query
1848: if (values.indexOf("#Call") >= 0) {
1849: int pos = values.indexOf("(");
1850: if (pos >= 0) {
1851: // get the string between the ( )'s, this is what needs to be passed back
1852: String name = values.substring(pos + 1, values
1853: .length() - 1);
1854: // now get the element on the property element
1855: Object pDisp = pEle.getElement();
1856: if (pDisp != null) {
1857: Class clazz = pDisp.getClass();
1858: try {
1859: Method getMethod = clazz
1860: .getMethod(name);
1861: if (getMethod != null) {
1862: Object value = getMethod
1863: .invoke(pDisp);
1864: if (value instanceof String) {
1865: String str = (String) value;
1866: pEle.setValue(str);
1867: pEle.setOrigValue(str);
1868: }
1869: }
1870: } catch (NoSuchMethodException e) {
1871:
1872: } catch (IllegalAccessException ie) {
1873:
1874: } catch (InvocationTargetException te) {
1875:
1876: }
1877: }
1878: }
1879: }
1880: }
1881: }
1882: }
1883:
1884: /**
1885: * The property definition states that the information to be displayed by the property element
1886: * should be a value from an expansion variable. Need to figure out what the value is.
1887: *
1888: * @param[in] pEle The property element to be used
1889: *
1890: * @return HRESULT
1891: *
1892: */
1893: private void processExpansionVar(IPropertyElement pEle) {
1894: if (pEle != null) {
1895: // get the definition
1896: IPropertyDefinition pDef = pEle.getPropertyDefinition();
1897: if (pDef != null) {
1898: // get its values
1899: String values = pDef.getValidValues();
1900: if (values != null && values.length() > 0) {
1901: // has it been tagged as an xpath query
1902: if (values.indexOf("#ExpansionVar") >= 0) {
1903: int pos = values.indexOf("(");
1904: if (pos >= 0) {
1905: // get the string between the ( )'s, this is what needs to be passed back
1906: String var = values.substring(pos + 1,
1907: values.length() - 1);
1908: // now get the element on the property element
1909: Object pDisp = pEle.getElement();
1910: if (pDisp instanceof IElement) {
1911: IElement pElement = (Element) pDisp;
1912: // get this element's dom node
1913: Node pNode = pElement.getNode();
1914: if (pNode != null) {
1915: // get the core product
1916: ICoreProduct pCoreProduct = ProductRetriever
1917: .retrieveProduct();
1918: if (pCoreProduct != null) {
1919: ITemplateManager pTemplateMgr = pCoreProduct
1920: .getTemplateManager();
1921: if (pTemplateMgr != null) {
1922: IVariableFactory pFactory = pTemplateMgr
1923: .getFactory();
1924: if (pFactory != null) {
1925: String config = pTemplateMgr
1926: .getConfigLocation();
1927: IVariableExpander expander = new VariableExpander();
1928: expander
1929: .setConfigFile(config);
1930: expander
1931: .setManager(pTemplateMgr);
1932: pFactory
1933: .setExecutionContext(expander);
1934: IExpansionVariable pVar = pFactory
1935: .createVariableWithText(var);
1936: if (pVar != null) {
1937: String text = pVar
1938: .expand(pNode);
1939: pEle.setValue(text);
1940: pEle
1941: .setOrigValue(text);
1942: }
1943: }
1944: }
1945: }
1946: }
1947: }
1948: }
1949: }
1950: }
1951: }
1952: }
1953: }
1954:
1955: }
|