blob: e1963a80fb0ed09c034a02b6e42216a5ee9610c8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.websvc.manager.ui;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLClassLoader;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
import org.openide.ErrorManager;
/**
*
* @author quynguyen
*/
public final class NodeHelper {
private final URLClassLoader loader;
private static NodeHelper instance;
private NodeHelper(URLClassLoader loader) {
this.loader = loader;
}
public static NodeHelper createInstance(URLClassLoader loader) {
NodeHelper result = new NodeHelper(loader);
NodeHelper.instance = result;
return result;
}
public static NodeHelper getInstance() {
return instance;
}
private URLClassLoader getRuntimeClassLoader() {
return loader;
}
/**
* Creates the node and all the child nodes with their associated TypeNodeData objects
*
* @param data the top-level node data
* @return a tree node with fully initialized children
*/
public DefaultMutableTreeNode createNodeFromData(TypeNodeData data)
throws WebServiceReflectionException {
DefaultMutableTreeNode node = null;
/**
* Now create the appropriate node to be added.
*/
String parameterClass = data.getTypeClass();
if (ReflectionHelper.isHolder(parameterClass)) {
node = new HolderTypeTreeNode(data, this.getRuntimeClassLoader());
DefaultMutableTreeNode childNode = null;
String holderType = data.getGenericType();
if (holderType == null) {
holderType = "java.lang.Object"; // NOI18N
data.setGenericType(holderType);
}
TypeNodeData heldData = ReflectionHelper.createTypeData(holderType, "value"); // NOI18N
heldData.setTypeValue(getParameterDefaultValue(heldData));
heldData.setAssignable(data.isAssignable());
// also initialize the Holder.value field in the parent data
ReflectionHelper.setHolderValue(data.getTypeValue(), heldData.getTypeValue());
childNode = createNodeFromData(heldData);
node.add(childNode);
} else if (ReflectionHelper.isJAXBElement(parameterClass)) {
node = new JAXBElementTreeNode(data, this.getRuntimeClassLoader());
TypeNodeData localPartData = ReflectionHelper.createTypeData("java.lang.String", "localPart"); // NOI18N
DefaultMutableTreeNode localPartNode = new DefaultMutableTreeNode(localPartData);
node.add(localPartNode);
String valueType = data.getGenericType();
if (valueType == null) {
valueType = "java.lang.Object"; // NOI18N
data.setGenericType(valueType);
}
TypeNodeData heldData = ReflectionHelper.createTypeData(valueType, "value"); // NOI18N
heldData.setTypeValue(getParameterDefaultValue(heldData));
heldData.setAssignable(data.isAssignable());
DefaultMutableTreeNode valueNode = createNodeFromData(heldData);
node.add(valueNode);
} else if (ReflectionHelper.isArray(parameterClass)) {
node = new ArrayTypeTreeNode(data, this.getRuntimeClassLoader());
addParameterArrayInstances(node);
} else if (ReflectionHelper.isCollection(data.getTypeClass(), getRuntimeClassLoader())) {
node = new ListTypeTreeNode(data, this.getRuntimeClassLoader());
addParameterArrayInstances(node);
} else if (ReflectionHelper.isComplexType(data.getTypeClass(), getRuntimeClassLoader())) {
node = new StructureTypeTreeNode(data, this.getRuntimeClassLoader());
traverseType(node);
} else {
node = new DefaultMutableTreeNode(data);
}
return node;
}
public DefaultMutableTreeNode createResultNodeFromData(TypeNodeData data) throws WebServiceReflectionException {
DefaultMutableTreeNode node = null;
String typeClass = data.getTypeClass();
if (ReflectionHelper.isCollection(typeClass, getRuntimeClassLoader())) {
node = new ListTypeTreeNode(data, this.getRuntimeClassLoader());
addResultArrayInstances(node);
}else if (ReflectionHelper.isComplexType(typeClass, getRuntimeClassLoader())) {
node = new StructureTypeTreeNode(data, this.getRuntimeClassLoader());
traverseResultType(node);
}else {
node = new DefaultMutableTreeNode(data);
}
return node;
}
private void traverseType(DefaultMutableTreeNode inNode) throws WebServiceReflectionException {
if(null == inNode) {
return;
}
TypeNodeData inData = (TypeNodeData)inNode.getUserObject();
String inType = inData.getTypeClass();
List<String> members = ReflectionHelper.getPropertyNames(inType, getRuntimeClassLoader());
for (String fieldName : members) {
String fieldType = ReflectionHelper.getPropertyType(inType, fieldName, getRuntimeClassLoader());
TypeNodeData childData = ReflectionHelper.createTypeData(fieldType, fieldName);
childData.setTypeValue(getParameterDefaultValue(childData));
if (!ReflectionHelper.isPropertySettable(inType, fieldName, getRuntimeClassLoader())) {
childData.setAssignable(false);
}
DefaultMutableTreeNode childNode = createNodeFromData(childData);
inNode.add(childNode);
}
}
private void traverseResultType(DefaultMutableTreeNode inParentNode) throws WebServiceReflectionException {
if(null == inParentNode) {
return;
}
TypeNodeData parentData = (TypeNodeData)inParentNode.getUserObject();
String parentType = parentData.getTypeClass();
Object parentValue = parentData.getTypeValue();
if (parentValue != null) {
List<String> members = ReflectionHelper.getPropertyNames(parentType, getRuntimeClassLoader());
for (String fieldName : members) {
String fieldType = ReflectionHelper.getPropertyType(parentType, fieldName, getRuntimeClassLoader());
Object fieldValue = ReflectionHelper.getPropertyValue(parentValue, fieldName, getRuntimeClassLoader());
TypeNodeData resultData = ReflectionHelper.createTypeData(fieldType, fieldName, fieldValue);
DefaultMutableTreeNode resultNode = createResultNodeFromData(resultData);
inParentNode.add(resultNode);
}
}
}
private void addParameterArrayInstances(DefaultMutableTreeNode parentNode) throws WebServiceReflectionException {
/**
* Now add some instances of the array.
* TODO: figure out some better way to pick the number of instances of the array to create
*/
TypeNodeData inData = (TypeNodeData)parentNode.getUserObject();
//String inTypeClass = inData.getTypeClass();
String elementType = inData.getGenericType();
for(int ii=0; ii < 9; ii++) {
TypeNodeData data = ReflectionHelper.createTypeData(elementType, "[" + ii + "]"); // NOI18N
data.setTypeValue(getParameterDefaultValue(data));
data.setAssignable(inData.isAssignable());
DefaultMutableTreeNode childNode = createNodeFromData(data);
parentNode.add(childNode);
}
}
private void addResultArrayInstances(DefaultMutableTreeNode parentNode) throws WebServiceReflectionException {
/**
* The result value is an array of a certain type that needs to be shown.
* 1. first get the type of the array.
* 2. create a node for each occurance of the array.
*
*/
TypeNodeData parentData = (TypeNodeData)parentNode.getUserObject();
//String parentType = parentData.getTypeClass();
String elementType = parentData.getGenericType();
if (elementType == null) {
elementType = "java.lang.Object"; // NOI18N
parentData.setGenericType(elementType);
}
Collection collection = (Collection)parentData.getTypeValue();
if (collection == null) return;
int i = 0;
for (Object nextValue : collection) {
TypeNodeData childData = ReflectionHelper.createTypeData(elementType, "[" + i + "]", nextValue);
DefaultMutableTreeNode childNode = createResultNodeFromData(childData);
parentNode.add(childNode);
i += 1;
}
}
/**
* This method will create a default value from a TypeNodeData object
*/
public Object getParameterDefaultValue(TypeNodeData data) {
assert data != null;
try {
String typeClass = data.getTypeClass();
if (ReflectionHelper.isComplexType(typeClass, getRuntimeClassLoader())) {
return ReflectionHelper.makeComplexType(typeClass, getRuntimeClassLoader());
} else if (ReflectionHelper.isCollection(typeClass, getRuntimeClassLoader())) {
return ReflectionHelper.makeCollection(typeClass, getRuntimeClassLoader());
} else if (ReflectionHelper.isHolder(typeClass)) {
return ReflectionHelper.makeHolder(getRuntimeClassLoader());
}else if (ReflectionHelper.isEnumeration(typeClass, getRuntimeClassLoader())) {
return ReflectionHelper.makeEnumeration(typeClass, getRuntimeClassLoader());
}else if (ReflectionHelper.isArray(typeClass)) {
return ReflectionHelper.makeGenericArray(data.getGenericType(), 0, getRuntimeClassLoader());
} else {
String currentType = typeClass;
Object value = null;
if (currentType.equals(int.class.getName()) || currentType.equals(Integer.class.getName())) {
value = Integer.valueOf(0);
} else if (currentType.equals(byte.class.getName()) || currentType.equals(Byte.class.getName())) {
value = Byte.valueOf("0");
} else if (currentType.equals(boolean.class.getName()) || currentType.equals(Boolean.class.getName())) {
value = false;
} else if (currentType.equals(float.class.getName()) || currentType.equals(Float.class.getName())) {
value = Float.valueOf(0);
} else if (currentType.equals(double.class.getName()) || currentType.equals(Double.class.getName())) {
value = Double.valueOf(0);
} else if (currentType.equals(long.class.getName()) || currentType.equals(Long.class.getName())) {
value = Long.valueOf(0);
} else if (currentType.equals(short.class.getName()) || currentType.equals(Short.class.getName())) {
value = Short.valueOf("0");
} else if (currentType.equals(String.class.getName())) {
value = "";
} else if (currentType.equals(BigDecimal.class.getName())) {
value = BigDecimal.valueOf(0);
} else if (currentType.equals(BigInteger.class.getName())) {
value = BigInteger.valueOf(0);
} else if (currentType.equals(URI.class.getName())) {
try {
value = new URI("http://java.sun.com");
} catch (URISyntaxException uri) {
}
} else if (currentType.equals(Calendar.class.getName())) {
value = Calendar.getInstance();
} else if (currentType.equalsIgnoreCase(Date.class.getName())) {
value = new Date();
}
return value;
}
} catch (WebServiceReflectionException wsre) {
Throwable cause = wsre.getCause();
ErrorManager.getDefault().notify(cause);
ErrorManager.getDefault().log(this.getClass().getName() + ": Error trying to do Class.forName on: " + data.getRealTypeName() + "WebServiceReflectionException=" + cause);
return null;
}
}
}