/* * Copyright 2013, Arondor * * Licensed 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 com.arondor.common.reflection.gwt.client.presenter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.logging.Logger; import com.arondor.common.reflection.bean.config.ObjectConfigurationBean; import com.arondor.common.reflection.bean.config.PrimitiveConfigurationBean; import com.arondor.common.reflection.gwt.client.presenter.fields.EnumTreeNodePresenter; import com.arondor.common.reflection.gwt.client.presenter.fields.ListTreeNodePresenter; import com.arondor.common.reflection.gwt.client.presenter.fields.MapTreeNodePresenter; import com.arondor.common.reflection.gwt.client.presenter.fields.PrimitiveTreeNodePresenter; import com.arondor.common.reflection.gwt.client.presenter.fields.StringListTreeNodePresenter; import com.arondor.common.reflection.gwt.client.service.GWTReflectionServiceAsync; import com.arondor.common.reflection.model.config.ObjectConfiguration; import com.arondor.common.reflection.model.config.ObjectConfigurationMap; import com.arondor.common.reflection.model.config.PrimitiveConfiguration; import com.arondor.common.reflection.model.java.AccessibleClass; import com.arondor.common.reflection.model.java.AccessibleField; import com.arondor.common.reflection.util.PrimitiveTypeUtil; import com.google.gwt.user.client.rpc.AsyncCallback; public class TreeNodePresenterFactory { private final static Logger LOG = Logger.getLogger(TreeNodePresenterFactory.class.getName()); private static final int MAX_DESCRIPTION_LENGTH = 60; public TreeNodePresenter createChildNodePresenter(GWTReflectionServiceAsync rpcService, ObjectConfigurationMap objectConfigurationMap, TreeNodePresenter.ChildCreatorDisplay display, AccessibleField accessibleField) { String fieldName = accessibleField.getName(); String fieldClassName = accessibleField.getClassName(); String fieldDescription = accessibleField.getDescription(); boolean mandatory = accessibleField.isMandatory(); String defaultValue = accessibleField.getDefaultValue(); boolean enumProperty = accessibleField.isEnumProperty(); List<String> genericTypes = accessibleField.getGenericParameterClassList(); return createChildNodePresenter(rpcService, objectConfigurationMap, display, fieldName, fieldClassName, fieldDescription, mandatory, defaultValue, enumProperty, accessibleField.getDeclaredInClass(), genericTypes); } public TreeNodePresenter createChildNodePresenter(GWTReflectionServiceAsync rpcService, ObjectConfigurationMap objectConfigurationMap, TreeNodePresenter.ChildCreatorDisplay display, String fieldName, final String fieldClassName, String fieldDescription, boolean isMandatory, String defaultValue, boolean isEnumProperty, final String classDeclaredIn, List<String> genericTypes) { TreeNodePresenter childPresenter = null; if (PrimitiveTypeUtil.isPrimitiveType(fieldClassName)) { LOG.finest("Field " + fieldName + " is primitive type"); childPresenter = new PrimitiveTreeNodePresenter(fieldName, display.createPrimitiveChild(fieldClassName)); if (defaultValue != null && !defaultValue.equals("")) { ((PrimitiveTreeNodePresenter) childPresenter).setDefaultValue(defaultValue); } PrimitiveConfiguration primitiveConfiguration = new PrimitiveConfigurationBean(); childPresenter.setElementConfiguration(primitiveConfiguration); } else if (isEnumProperty) { LOG.finest("Field " + fieldName + " is associated with enum type"); childPresenter = createEnumListPresenter(rpcService, display, fieldName, fieldClassName, classDeclaredIn); } else if (isStringListField(fieldClassName, genericTypes)) { LOG.finest("Field " + fieldName + " is a string list"); childPresenter = new StringListTreeNodePresenter(fieldName, display.createStringListChild()); } else if (fieldClassName.equals("java.util.Map") && genericTypes != null && genericTypes.size() == 2) { LOG.severe("Field " + fieldName + " is an object map of " + genericTypes.get(0) + ", " + genericTypes.get(1)); childPresenter = new MapTreeNodePresenter(rpcService, objectConfigurationMap, fieldName, genericTypes, display.createMapChild()); } else if (fieldClassName.equals("java.util.List") && genericTypes != null && genericTypes.size() == 1) { LOG.finest("Field " + fieldName + " is an " + genericTypes.get(0) + " list"); String genericType = genericTypes.get(0); childPresenter = new ListTreeNodePresenter(rpcService, objectConfigurationMap, fieldName, genericType, display.createListChild()); } else { LOG.finest("Field " + fieldName + " is an object " + fieldClassName); childPresenter = new ClassTreeNodePresenter(rpcService, objectConfigurationMap, fieldName, fieldClassName, display.createClassChild()); } setNodeNameAndDescription(fieldName, fieldClassName, fieldDescription, isMandatory, childPresenter); return childPresenter; } private TreeNodePresenter createEnumListPresenter(GWTReflectionServiceAsync rpcService, TreeNodePresenter.ChildCreatorDisplay display, String fieldName, final String fieldClassName, final String classDeclaredIn) { final EnumTreeNodePresenter childPresenter = new EnumTreeNodePresenter(fieldName, display.createEnumListChild()); if (classDeclaredIn != null) { rpcService.getAccessibleClass(classDeclaredIn, new AsyncCallback<AccessibleClass>() { public void onSuccess(AccessibleClass result) { LOG.finest("Retrieve enum class : " + result.getClassBaseName()); Map<String, List<String>> enumValuesMap = result.getAccessibleEnums(); if (enumValuesMap == null || enumValuesMap.isEmpty()) { LOG.warning("No enum type defined for class : " + fieldClassName); return; } List<String> enumVals = enumValuesMap.get(fieldClassName); if (enumVals == null || enumVals.isEmpty()) { LOG.warning("Impossible to get enumtype values for " + fieldClassName); return; } final List<String> enumValues = new ArrayList<String>(); enumValues.addAll(enumVals); if (enumValues.isEmpty()) { LOG.warning("Impossible to get values for enum : " + fieldClassName); } else { childPresenter.setEnumValues(enumValues); } } public void onFailure(Throwable caught) { } }); } ObjectConfiguration objectConfiguration = new ObjectConfigurationBean(); childPresenter.setElementConfiguration(objectConfiguration); return childPresenter; } private void setNodeNameAndDescription(String fieldName, String fieldClassName, String fieldDescription, boolean isMandatory, TreeNodePresenter childPresenter) { String nodeName; String nodeDescription = ""; if (isMandatory) { nodeDescription = "* "; } if (fieldDescription != null) { if (fieldDescription.length() >= MAX_DESCRIPTION_LENGTH) { nodeName = nodeDescription + fieldDescription.substring(0, MAX_DESCRIPTION_LENGTH) + "..."; nodeDescription += fieldDescription; } else { nodeName = nodeDescription + fieldDescription; nodeDescription += fieldDescription; } } else { nodeName = fieldName; } nodeDescription += " (" + fieldName + " : " + fieldClassName + ")"; childPresenter.getDisplay().setNodeDescription(nodeDescription); childPresenter.getDisplay().setNodeName(nodeName); } private boolean isStringListField(String fieldClassName, List<String> genericTypes) { return fieldClassName.equals("java.util.List") && genericTypes != null && genericTypes.size() == 1 && genericTypes.get(0).equals("java.lang.String"); } private final static TreeNodePresenterFactory INSTANCE = new TreeNodePresenterFactory(); public static TreeNodePresenterFactory getInstance() { return INSTANCE; } }