/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.model.pv; import java.util.*; import org.eclipse.jdt.core.*; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.XModelObjectConstants; import org.jboss.tools.common.model.impl.RegularObjectImpl; import org.jboss.tools.common.model.util.EclipseJavaUtil; import org.jboss.tools.common.util.BeanUtil; import org.jboss.tools.jsf.JSFModelPlugin; public class JSFProjectBean extends RegularObjectImpl { public static final String ENTITY = "JSFProjectBean"; public static final String ATTR_CLASS_NAME = "class name"; private static final long serialVersionUID = 3044316361003259426L; protected JSFProjectBeans beans = null; protected XModelObject[] beanList = new XModelObject[0]; protected IType type = null; protected boolean isLoading = false; protected boolean loaded = false; public String getPresentationString() { String s = "" + getAttributeValue(ATTR_CLASS_NAME); int d = s.lastIndexOf('.'); if(d >= 0) s = s.substring(d + 1); return s; } public boolean isAttributeEditable(String name) { return false; } public void setBeans(JSFProjectBeans beans) { this.beans = beans; } void cleanBeans() { beanList = new XModelObject[0]; } void addBean(XModelObject bean) { XModelObject[] l = new XModelObject[beanList.length + 1]; System.arraycopy(beanList, 0, l, 0, beanList.length); l[beanList.length] = bean; beanList = l; } public XModelObject[] getBeanList() { return beanList; } public void setType(IType type) { this.type = type; if(loaded) { try { update(); } catch (JavaModelException e) { JSFModelPlugin.getPluginLog().logError(e); } } } public IType getType() { return type; } protected void loadChildren() { if(loaded) return; loaded = true; isLoading = true; try { update(); } catch (JavaModelException e) { JSFModelPlugin.getPluginLog().logError(e); } isLoading = false; } public boolean hasChildren() { if(type == null) return false; if(!loaded) return true; return super.hasChildren(); } public void update() throws JavaModelException { if(!loaded) return; Map<String,XModelObject> map = new HashMap<String,XModelObject>(); Set<String> properties = new HashSet<String>(); XModelObject[] cs = getChildren(); for (int i = 0; i < cs.length; i++) map.put(cs[i].getPathPart(), cs[i]); if(type != null) { IType _type = type; Set<IType> interfaces = new HashSet<IType>(); while(_type != null) { IField[] fs = _type.getFields(); if(fs != null) for (int i = 0; i < fs.length; i++) { String n = fs[i].getElementName(); if(properties.contains(n)) continue; JSFProjectBeanMember c = (JSFProjectBeanMember)map.get(n); if(c != null && !c.getModelEntity().getName().equals("JSFProjectBeanProperty")) { c.removeFromParent(); map.remove(n); c = null; } if(c != null) { map.remove(n); String typeName = EclipseJavaUtil.getMemberTypeAsString(fs[i]); c.setType(beans.getType(typeName)); if(typeName == null) typeName = ""; c.setAttributeValue(ATTR_CLASS_NAME, typeName); c.setAttributeValue("declaring class", fs[i].getDeclaringType().getFullyQualifiedName()); } else { c = createMember(n, fs[i], "JSFProjectBeanProperty"); } properties.add(n); } IMethod[] ms = _type.getMethods(); if(ms != null) for (int i = 0; i < ms.length; i++) { if(ms[i].isConstructor()) continue; if(!Flags.isPublic(ms[i].getFlags()) && !_type.isInterface()) continue; String n = ms[i].getElementName(); boolean isProperty = false; if(BeanUtil.isGetter(ms[i]) || BeanUtil.isSetter(ms[i])) { String propertyName = BeanUtil.getPropertyName(n); if(propertyName != null) { n = propertyName; isProperty = true; } } String entity = (isProperty) ? "JSFProjectBeanProperty" : "JSFProjectBeanMethod"; JSFProjectBeanMember c = (JSFProjectBeanMember)map.get(n); if(c != null && !c.getModelEntity().getName().equals(entity)) { c.removeFromParent(); map.remove(n); c = null; } if(c != null) { map.remove(n); String typeName = EclipseJavaUtil.getMemberTypeAsString(ms[i]); c.setType(beans.getType(typeName)); if(typeName == null) typeName = ""; c.setAttributeValue(ATTR_CLASS_NAME, typeName); c.setMember(ms[i]); c.setAttributeValue("declaring class", ms[i].getDeclaringType().getFullyQualifiedName()); } else if(!properties.contains(n)) { c = createMember(n, ms[i], entity); } if(isProperty) { properties.add(n); } else { //add it anyway properties.add(n); } } String[] is = _type.getSuperInterfaceNames(); for (int i = 0; i < is.length; i++) { String in = EclipseJavaUtil.resolveType(_type, is[i]); if(in != null && in.length() > 0) { IType it = beans.getType(in); if(it != null) interfaces.add(it); } } String sc = _type.getSuperclassName(); if(sc == null || sc.length() == 0 || "java.lang.Object".equals(sc)) break; sc = EclipseJavaUtil.resolveType(_type, sc); if(sc == null || sc.length() == 0 || "java.lang.Object".equals(sc)) break; _type = beans.getType(sc); } Set<IType> allInterfaces = new HashSet<IType>(); while(!interfaces.isEmpty()) { allInterfaces.addAll(interfaces); Set<IType> interfaces2 = new HashSet<IType>(); for (IType t : interfaces) { IField[] fs = t.getFields(); if (fs != null) for (int i = 0; i < fs.length; i++) { String n = fs[i].getElementName(); if (properties.contains(n)) continue; JSFProjectBeanMember c = (JSFProjectBeanMember) map.get(n); if (c != null && !c.getModelEntity().getName().equals("JSFProjectBeanProperty")) { c.removeFromParent(); map.remove(n); c = null; } if (c != null) { map.remove(n); String typeName = EclipseJavaUtil.getMemberTypeAsString(fs[i]); c.setType(beans.getType(typeName)); if (typeName == null) typeName = ""; c.setAttributeValue(ATTR_CLASS_NAME, typeName); c.setAttributeValue("declaring class", fs[i].getDeclaringType().getFullyQualifiedName()); } else { c = createMember(n, fs[i], "JSFProjectBeanProperty"); } properties.add(n); } String[] is = t.getSuperInterfaceNames(); for (int i = 0; i < is.length; i++) { String in = EclipseJavaUtil.resolveType(_type, is[i]); if(in != null && in.length() > 0) { IType it = beans.getType(in); if(it != null && !allInterfaces.contains(it)) interfaces2.add(it); } } } interfaces = interfaces2; } } else if(beanList.length > 0) { XModelObject[] ps = beanList[0].getChildren(); for (int i = 0; i < ps.length; i++) { String n = ps[i].getPathPart(); JSFProjectBeanMember c = (JSFProjectBeanMember)map.get(n); if(c != null) { map.remove(n); } else { c = (JSFProjectBeanMember)getModel().createModelObject("JSFProjectBeanProperty", null); c.setAttributeValue(XModelObjectConstants.ATTR_NAME, n); c.setBeans(beans); c.setType(null); addChild(c); } } } for(XModelObject o: map.values()) { o.removeFromParent(); } } JSFProjectBeanMember createMember(String n, IMember member, String entity) { JSFProjectBeanMember c = (JSFProjectBeanMember)getModel().createModelObject(entity, null); c.setAttributeValue(XModelObjectConstants.ATTR_NAME, n); c.setBeans(beans); String className = EclipseJavaUtil.getMemberTypeAsString(member); c.setAttributeValue(ATTR_CLASS_NAME, (className == null) ? "" : className); c.setAttributeValue("declaring class", member.getDeclaringType().getFullyQualifiedName()); c.setType(beans.getType(className)); c.setMember(member); if(isLoading) addChild_0(c); else addChild(c); return c; } }