/* * Copyright (C) 2000 - 2008 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ */ package com.naryx.tagfusion.cfm.xml.ws.dynws; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.nary.util.FastMap; import com.naryx.tagfusion.cfm.engine.cfArrayData; import com.naryx.tagfusion.cfm.engine.cfComponentData; import com.naryx.tagfusion.cfm.engine.cfData; import com.naryx.tagfusion.cfm.engine.cfDataFactory; import com.naryx.tagfusion.cfm.engine.cfSession; import com.naryx.tagfusion.cfm.engine.cfStringData; import com.naryx.tagfusion.cfm.engine.cfStructData; import com.naryx.tagfusion.cfm.engine.cfmRunTimeException; public class CFCDescriptor { private cfStructData md = null; private cfStructData[] fxns = null; private cfArrayData[] parms = null; private cfStructData[] props = null; private cfSession session = null; public CFCDescriptor(cfStructData md, cfSession sess) { this.md = md; this.session = sess; init(); } protected void init() { cfStructData localMd = null; List prevParents = new LinkedList(); // Get the functions, parameters localMd = this.md; prevParents.clear(); Map fMap = new FastMap(); while (localMd != null) { cfStructData f = null; cfArrayData tmp = null; cfStringData axs = null; cfData fName = null; cfData fReturnType = null; cfArrayData allFxns = (cfArrayData) localMd.getData("FUNCTIONS"); if (allFxns != null) { for (int i = 0; i < allFxns.size(); i++) { f = (cfStructData) allFxns.getElement(i + 1); axs = (cfStringData) f.getData("ACCESS"); fName = f.getData("NAME"); fReturnType = f.getData("RETURNTYPE"); if (axs != null && axs.toString().toLowerCase().equalsIgnoreCase("remote") && fName != null && !fMap.containsKey(fName.toString())) { // If the function doesn't specify a returnType then throw an // exception. Fix for bug NA#2934. if (fReturnType == null) throw new IllegalStateException("The function '" + fName + "' must specify a returnType attribute."); tmp = (cfArrayData) f.getData("PARAMETERS"); if (tmp == null) tmp = cfArrayData.createArray(1); fMap.put(fName.toString(), new Object[] { f, tmp }); } } } localMd = getSuperMetaData(localMd, prevParents); } fxns = new cfStructData[fMap.size()]; parms = new cfArrayData[fMap.size()]; Iterator itr = fMap.values().iterator(); for (int i = 0; itr.hasNext(); i++) { Object[] fp = (Object[]) itr.next(); fxns[i] = (cfStructData) fp[0]; parms[i] = (cfArrayData) fp[1]; } // Get the properties localMd = this.md; prevParents.clear(); Map prMap = new HashMap(); while (localMd != null) { cfStructData pr = null; cfArrayData allProps = (cfArrayData) localMd.getData("PROPERTIES"); if (allProps != null) { for (int i = 0; i < allProps.size(); i++) { pr = (cfStructData) allProps.getElement(i + 1); cfData prName = pr.getData("NAME"); if (prName != null && !prMap.containsKey(prName.toString())) prMap.put(prName.toString(), pr); } } localMd = getSuperMetaData(localMd, prevParents); } props = (cfStructData[]) prMap.values().toArray(new cfStructData[prMap.values().size()]); } protected cfStructData getSuperMetaData(cfStructData localMd, List prevParents) { cfStructData smd = (cfStructData) localMd.getData("EXTENDS"); if (smd != null) { if (!prevParents.contains(smd.getData("NAME").toString())) { prevParents.add(smd.getData("NAME").toString()); return smd; } } return null; } public File getFile() { return new File(md.getData("PATH").toString()); } public String getPath() { return md.getData("PATH").toString(); } public String getName() { return md.getData("NAME").toString(); } public String getDescription() { if (md.getData("HINT") != null) return md.getData("HINT").toString(); else return null; } public int getPropertyCount() { return props.length; } public String getPropertyName(int ndx) { cfStructData pr = getProperty(ndx); if (pr != null && pr.getData("NAME") != null) return pr.getData("NAME").toString(); else return null; } public String getPropertyDescription(int ndx) { cfStructData pr = getProperty(ndx); if (pr != null && pr.getData("HINT") != null) return pr.getData("HINT").toString(); else return null; } public String getPropertyType(int ndx, DynamicWebServiceTypeGenerator gen) { cfStructData pr = getProperty(ndx); if (pr != null && pr.getData("TYPE") != null) return findType(pr.getData("TYPE").toString().trim(), gen); else return null; } public int getFunctionCount() { return fxns.length; } public String getFunctionName(int ndx) { cfStructData f = getFunction(ndx); if (f != null && f.getData("NAME") != null) return f.getData("NAME").toString(); else return null; } public String getFunctionDescription(int ndx) { cfStructData f = getFunction(ndx); if (f != null && f.getData("HINT") != null) return f.getData("HINT").toString(); else return null; } public String getFunctionReturnType(int ndx, DynamicWebServiceTypeGenerator gen) { cfStructData f = getFunction(ndx); if (f != null && f.getData("RETURNTYPE") != null) return findType(f.getData("RETURNTYPE").toString().trim(), gen); else return null; } public int getFunctionParameterCount(int ndx) { cfArrayData parms = getParameters(ndx); if (parms != null) return parms.size(); else return 0; } public String getFunctionParameterName(int fxnNdx, int parmNdx) { cfStructData p = getParameter(fxnNdx, parmNdx); if (p != null && p.getData("NAME") != null) return p.getData("NAME").toString(); else return null; } public String getFunctionParameterType(int fxnNdx, int parmNdx, DynamicWebServiceTypeGenerator gen) { cfStructData p = getParameter(fxnNdx, parmNdx); if (p != null && p.getData("TYPE") != null) return findType(p.getData("TYPE").toString().trim(), gen); else return null; } protected cfStructData getFunction(int ndx) { if (ndx < fxns.length) return fxns[ndx]; else return null; } protected cfArrayData getParameters(int ndx) { if (ndx < parms.length) return parms[ndx]; else return null; } protected cfStructData getParameter(int ndx1, int ndx2) { cfArrayData parmsArray = getParameters(ndx1); if (parmsArray != null && ndx2 < parmsArray.size()) return (cfStructData) parmsArray.getElement(ndx2 + 1); else return null; } protected cfStructData getProperty(int ndx) { if (ndx < props.length) return props[ndx]; else return null; } protected String findType(String rawType, DynamicWebServiceTypeGenerator gen) { // Try a standard type Class typ = cfDataFactory.getDatatypeJavaClass(rawType); if (typ != null) { if (typ.isArray()) return typ.getComponentType().getName() + "[]"; else return typ.getName(); } // Try a CFC type String cfcT = findCFCType(rawType, gen); if (cfcT != null) return cfcT; // Handle void types if (rawType.equalsIgnoreCase("void")) return rawType; // We don't know this type, so... throw new IllegalArgumentException("Unrecognized type encountered: " + rawType); } protected String findCFCType(String rawType, DynamicWebServiceTypeGenerator gen) { cfComponentData cfc = null; String nsLocal = null; String fullyQual = rawType; if (rawType.indexOf(".") == -1) nsLocal = getName().substring(0, getName().lastIndexOf(".") + 1) + rawType; // Try ns local if we have it if (nsLocal != null) { try { cfc = new cfComponentData(session, nsLocal); } catch (cfmRunTimeException ex) { } } if (cfc != null) return genCFCType(cfc, gen); // Try fully qualified try { cfc = new cfComponentData(session, fullyQual); } catch (cfmRunTimeException ex) { } if (cfc != null) return genCFCType(cfc, gen); return null; } protected String genCFCType(cfComponentData cfc, DynamicWebServiceTypeGenerator gen) { String type = cfc.getMetaData().getData("NAME").toString().trim(); String full = DynamicWebServiceTypeGenerator.getFQName(type); String knownType = gen.getKnownType(full); if (knownType == null) gen.addType(new CFCDescriptor(cfc.getMetaData(), session)); else full = knownType; return full; } }