|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.java.bridge; import java.beans.PropertyChangeEvent; import java.util.*; import org.netbeans.jmi.javamodel.ClassDefinition; import org.netbeans.jmi.javamodel.JavaClass; import org.openide.src.*; import javax.jmi.reflect.RefObject; import javax.jmi.reflect.RefBaseObject; import javax.jmi.reflect.InvalidObjectException; import org.netbeans.api.mdr.events.*; import org.netbeans.jmi.javamodel.CallableFeature; import org.netbeans.jmi.javamodel.Type; import org.netbeans.jmi.javamodel.TypeClass; import org.netbeans.jmi.javamodel.Parameter; import org.netbeans.jmi.javamodel.ParameterClass; import org.netbeans.jmi.javamodel.IsOfType; import org.netbeans.jmi.javamodel.MultipartId; import org.netbeans.jmi.javamodel.Throws; import org.netbeans.jmi.javamodel.TypeReference; import org.netbeans.modules.javacore.jmiimpl.javamodel.TypeClassImpl; /** * * @author sdedic * @version */ abstract class CallableImpl extends MemberElementImpl implements ConstructorElement.Impl { private static final boolean DEBUG = false; /** Special tag value for methods without parameters (performance enhancement) */ static final MethodParameter[] NO_PARAMETERS = new MethodParameter[0]; /** Flyweight support for PROP_EXCEPTION property. */ private static IdentifierArrayProperty exceptionSupport; /** Flyweight support for PROP_PARAMETERS property. */ private static MethodParamSupport paramSupport; private transient long bodyHash = -1; private static final long serialVersionUID = -357084137587082234L; // Construction /////////////////////////////////////////////////////////////////////////////////// CallableImpl(DefaultLangModel model, CallableFeature javaElement) { super(model, javaElement); init (); } private void init () { if (paramSupport == null) { paramSupport = new MethodParamSupport(); exceptionSupport = new ExceptionSupport(); } javadoc = new JavaDocImpl.Method(null, this); } public org.openide.src.JavaDoc.Method getJavaDoc() { updateJavadoc(); return (org.openide.src.JavaDoc.Method)javadoc; } /* protected void copyBody(String bodyContent) { cachedBody = bodyContent; } void updateBody(String content) { if (content == null) { bodyHash = -1; return; } long newHash = computeHash(content); if (newHash == bodyHash) return; if (DEBUG) { System.err.println("[" + this + "] updating body to \"" + content + "\""); // NOI18N System.err.println("[" + this + "] hash is " + newHash + " old hash = " + bodyHash); // NOI18N } if (bodyHash != -1) { addPropertyChange(new PropertyChangeEvent(getElement(), PROP_BODY, null, null)); } bodyHash = newHash; } */ // Getters /////////////////////////////////////////////////////////////////////////////// /** * Returns parameters for the method. * @return array of parameter descriptions. */ public final MethodParameter[] getParameters() { MethodParameter[] parameters; repository.beginTrans (false); try { setClassPath(); Collection list = ((CallableFeature) javaElement).getParameters (); Iterator iter; if (list.size () == 0) parameters = NO_PARAMETERS; else { iter = list.iterator (); parameters = new MethodParameter [list.size ()]; for (int x = 0; iter.hasNext (); x++) { Parameter param = (Parameter) iter.next (); parameters [x] = createParameter(param); } // for } // else } catch (InvalidObjectException e) { return NO_PARAMETERS; } finally { repository.endTrans (false); } return parameters; } /** Retrieves checked exceptions declared to be thrown from the callable. * @return Identifiers representing exception types thrown from the method. */ public final Identifier[] getExceptions() { Identifier[] exceptions; repository.beginTrans (false); try { setClassPath(); Collection list = ((CallableFeature) javaElement).getExceptionNames (); if (list.size () == 0) exceptions = IdentifierArrayProperty.EMPTY; else { Iterator iter = list.iterator (); exceptions = new Identifier [list.size ()]; for (int x = 0; iter.hasNext (); x++) { MultipartId ex = (MultipartId) iter.next (); exceptions [x] = createClassIdentifier (ex); } // for } // else } catch (InvalidObjectException e) { return new Identifier [0]; } finally { repository.endTrans (false); } return exceptions; } /** Retrieves body of the method. */ public final String getBody() { repository.beginTrans (false); try { setClassPath(); return ((CallableFeature)javaElement).getBodyText(); } catch (InvalidObjectException e) { return null; } finally { repository.endTrans (false); } } /* protected void notifyCreate() { super.notifyCreate(); if (cachedBody != null) { String body; cachedBody = null; body = getBody(); if (body != null) bodyHash = computeHash(body); } } */ private long computeHash(String bodyContent) { java.util.zip.CRC32 crc = new java.util.zip.CRC32(); crc.update(bodyContent.getBytes()); return crc.getValue(); } protected void createFromModel(Element model) throws SourceException { super.createFromModel(model); ConstructorElement m = (ConstructorElement)model; setParameters(m.getParameters()); setExceptions(m.getExceptions()); setBody(m.getBody()); setJavaDocText(m.getJavaDoc().getRawText(), true); } // Setters /////////////////////////////////////////////////////////////////////////////// public void setParameters(MethodParameter[] params) throws SourceException { checkWritable(); checkDocument(); boolean failed = true; repository.beginTrans (true); try { PropertyChangeEvent evt; setClassPath(); params = resolveParams(params); evt = paramSupport.createChangeEvent(getElement(), params == null ? NO_PARAMETERS : getParameters (), params); if (evt == null) { failed = false; checkIsValid (); return; } checkVetoablePropertyChange(evt); if (params == null) params = NO_PARAMETERS; ParameterClass proxy = javaModelPackage.getParameter (); Collection pars = ((CallableFeature) javaElement).getParameters (); Collection temp = new LinkedList (); pars.clear(); for (int x = 0; x < params.length; x++) { Parameter p = proxy.createParameter ( params [x].getName (), null, params [x].isFinal (), null, 0, false ); p.setTypeName (typeToTypeReference (params [x].getType ())); temp.add (p); } pars.addAll (temp); failed = false; } catch (InvalidObjectException e) { throwIsInvalid (); } finally { repository.endTrans (failed); } } MethodParameter createParameter (Parameter param) { try { org.openide.src.Type type = param.isVarArg() ? stringToType("java.lang.Object[]") : descrToType(param.getType()); // NOI18N return new MethodParameter ( param.getName (), type, param.isFinal () ); } catch (InvalidObjectException e) { return new MethodParameter ("", null, false); } } MethodParameter createParameterConn (Parameter param) { try { org.openide.src.Type type = null; if (param.getType() instanceof ClassDefinition) { type = org.openide.src.Type.createClass(Identifier.create(param.getType().getName())); } else { type = descrToType(param.getType()); } return new MethodParameter ( param.getName (), type, param.isFinal () ); } catch (InvalidObjectException e) { return new MethodParameter ("", null, false); } } private MethodParameter resolveParameter(MethodParameter par) { org.openide.src.Type t = resolveType(par.getType()); if (t == par.getType()) return par; return new MethodParameter( par.getName(), t, par.isFinal()); } private MethodParameter[] resolveParams(MethodParameter[] params) { return params; // [PENDING] /* if (!isConstrained()) return params; int[] map = paramSupport.pairItems(this.parameters, params); MethodParameter[] newParams = null; for (int i = 0; i< map.length; i++) { if (map[i] == -1) { MethodParameter p = resolveParameter(params[i]); if (p == params[i]) continue; if (newParams == null) { newParams = new MethodParameter[params.length]; System.arraycopy(params, 0, newParams, 0, params.length); } newParams[i] = p; } } return newParams == null ? params : newParams; */ } public void setExceptions(Identifier[] except) throws SourceException { checkWritable(); checkDocument(); boolean failed = true; repository.beginTrans (true); try { setClassPath(); except = resolveIdentifiers(except); PropertyChangeEvent evt; evt = exceptionSupport.createChangeEvent(getElement(), getExceptions (), except); if (evt == null) { failed = false; checkIsValid (); return; } checkVetoablePropertyChange(evt); if (except == null) except = IdentifierArrayProperty.EMPTY; Collection excs = ((CallableFeature)javaElement).getExceptionNames (); Collection temp = new LinkedList (); for (int x = 0; x < except.length; x++) { MultipartId id = javaModelPackage.getMultipartId().createMultipartId(except[x].getFullName(), null, null); temp.add (id); } excs.clear(); excs.addAll (temp); failed = false; } catch (InvalidObjectException e) { throwIsInvalid (); } finally { repository.endTrans (failed); } } /** * Sets the text of the body to the passed value. Note, that PropertyChangeEvent * fired on behalf of this change may contain other value because the underlying * binding mechanism may change the exact layout of the body (no semantic changes * are permitted). * @throw SourceException if a VetoableListener disagrees or other error occurs. */ public final void setBody(String body) throws SourceException { checkWritable(); checkDocument(); repository.beginTrans (true); boolean rollback = true; try { PropertyChangeEvent evt; setClassPath(); String cachedBody = getBody (); if (cachedBody == body || (cachedBody != null && body != null && cachedBody.equals(body))) { checkIsValid (); return; } evt = new PropertyChangeEvent(getElement(), PROP_BODY, cachedBody, body); checkVetoablePropertyChange(evt); ((CallableFeature)javaElement).setBodyText(body); rollback = false; } catch (InvalidObjectException e) { throwIsInvalid (); } finally { repository.endTrans (rollback); } } public void fireChangeParameters (MethodParameter[] oldPars, MethodParameter[] newPars, MethodParameter[] oldParsConn) { PropertyChangeEvent evt; evt = paramSupport.createChangeEvent( getElement(), oldPars, newPars ); if (evt == null) { return; } fireOwnPropertyChange (evt); ConstructorElement elem = (ConstructorElement) cloneSelf (); try { elem.setParameters (oldParsConn); } catch (SourceException e) { e.printStackTrace (); } notifyConnectionChange (elem); } public void fireChangeExceptions(Identifier[] oldExcs, Identifier[] newExcs) { oldExcs = resolveIdentifiers(oldExcs); newExcs = resolveIdentifiers(newExcs); PropertyChangeEvent evt; evt = exceptionSupport.createChangeEvent(getElement(), oldExcs, newExcs); if (evt == null) { return; } fireOwnPropertyChange (evt); ConstructorElement elem = (ConstructorElement) cloneSelf (); try { elem.setExceptions (oldExcs); } catch (SourceException e) { e.printStackTrace (); } notifyConnectionChange (elem); } public void fireChangeBody (String oldVal, String newVal) { PropertyChangeEvent evt = new PropertyChangeEvent(getElement(), PROP_BODY, oldVal, newVal); fireOwnPropertyChange(evt); } // Private protocol ///////////////////////////////////////////////////////////////////////////////// protected void initializeListenerSupport() { if (exceptionSupport == null) { synchronized (CallableImpl.class) { if (exceptionSupport == null) exceptionSupport = new ExceptionSupport(); } } if (paramSupport == null) { synchronized (CallableImpl.class) { if (paramSupport == null) paramSupport = new MethodParamSupport(); } } } // Support classes ///////////////////////////////////////////////////////////////////////////////// private static final class MethodParamSupport extends FlyweightIndexedProperty { MethodParamSupport() { super(PROP_PARAMETERS); } protected final Object[] createEmpty() { return NO_PARAMETERS; } protected final Object[] createValue(int size) { if (size == 0) return createEmpty(); return new MethodParameter[size]; } protected boolean compareValues(Object a, Object b) { MethodParameter par1 = (MethodParameter)a; MethodParameter par2 = (MethodParameter)b; org.openide.src.Type t1 = par1.getType(); org.openide.src.Type t2 = par2.getType(); if (!par1.getName().equals(par2.getName())) return false; if (par1.isFinal() != par2.isFinal()) return false; return compareSourceTypes(t1, t2); } protected final Object[] getValue(ElementImpl impl) { return ((CallableImpl)impl).getParameters (); } } private static final class ExceptionSupport extends IdentifierArrayProperty { ExceptionSupport() { super(PROP_EXCEPTIONS); } public Object[] getAsArray(ElementImpl bean) { return ((CallableImpl)bean).getExceptions (); } protected final Object[] getValue(ElementImpl impl) { return ((CallableImpl)impl).getExceptions (); } public boolean compareValues(Object one, Object two) { return compareSourceIdentifiers((Identifier)one, (Identifier)two); } } protected void copyCallableProperties(ConstructorElement el) { try { el.setName(getName()); el.setModifiers(getModifiers()); el.setParameters(getParameters()); el.setExceptions(getExceptions()); } catch (SourceException ex) { } } // .......................................................................... static class CallableListener extends MemberElementImpl.MemberElementListener { private static final MethodParameter[] NO_PARAMETERS = new MethodParameter[0]; private static final Identifier[] NO_IDENTIFIERS = new Identifier[0]; ParametersListener params = new ParametersListener (this); ExceptionsListener exceptions = new ExceptionsListener (this); CallableListener (CallableImpl impl) { super (impl); } public void connect () { if (REGISTER_LISTENER) { super.connect (); impl = (ElementImpl) ref.get(); if (impl != null) { params.initElements (); exceptions.initElements (); } impl = null; } } public void remove () { super.remove (); params.removeAll (); exceptions.removeAll (); } public void doChange(MDRChangeEvent event) { super.doChange (event); if (event instanceof AttributeEvent) { AttributeEvent attrEv = (AttributeEvent) event; if (attrEv.getAttributeName ().equals ("bodyText")) { // NOI18N ((CallableImpl) impl).fireChangeBody ( (String) attrEv.getOldElement (), (String) attrEv.getNewElement () ); } } } } // CallableListener ....................................................... static class ExceptionsListener implements MDRPreChangeListener { protected ElementImpl.ElementListener parentListener; protected RefObject javaElement; private ArrayList exIds = new ArrayList(); private Map eventsMap = new HashMap(); ExceptionsListener(ElementImpl.ElementListener parentListener) { this.parentListener = parentListener; javaElement = parentListener.javaElement; } // ----------- public List getElements() { return ((CallableFeature) javaElement).getExceptions(); } public String getEndName() { return "exceptions"; // NOI18N } public void fireChange (ElementImpl impl, ArrayList oldValues, ArrayList newValues) { Identifier [] oldPars = (Identifier []) oldValues.toArray (CallableListener.NO_IDENTIFIERS); Identifier [] newPars = (Identifier []) newValues.toArray (CallableListener.NO_IDENTIFIERS); ((CallableImpl) impl).fireChangeExceptions (oldPars, newPars); } // ----------- public void initElements () { Iterator iter = getElements().iterator(); while (iter.hasNext()) { JavaClass ex = (JavaClass) iter.next(); exIds.add(Identifier.create(ex.getName())); } ((MDRChangeSource) javaElement).addListener(this, AssociationEvent.EVENTMASK_ASSOCIATION); } public void removeAll () { exIds.clear(); try { ((MDRChangeSource) javaElement).removeListener (this); } catch (InvalidObjectException e) { } } public int findIndex (String name) { int size = exIds.size (); Iterator iter = exIds.iterator (); for (int x = 0; x < size; x++) { Identifier id = (Identifier) iter.next(); if (id.getName().equals(name)) return x; } return -1; } public final void change(MDRChangeEvent event) { if (!parentListener.isValid) return; ElementImpl impl = parentListener.getImpl (); if (impl == null) { parentListener.remove (); return; } if (event instanceof AssociationEvent) { AssociationEvent assocEvent = (AssociationEvent) event; String endName = getEndName(); if (getEndName().equals(assocEvent.getEndName())) { EventInfo info = (EventInfo)eventsMap.remove(event); ArrayList old = (ArrayList) exIds.clone(); int index; int position = info.index; if (event.isOfType (AssociationEvent.EVENT_ASSOCIATION_SET)) { index = position != AssociationEvent.POSITION_NONE ? position : findIndex(info.oldName); if (index < 0 || index >= exIds.size()) // [PENDING] return; exIds.set (index, Identifier.create(info.newName)); } else if (event.isOfType (AssociationEvent.EVENT_ASSOCIATION_REMOVE)) { index = position != AttributeEvent.POSITION_NONE ? position : findIndex(info.oldName); if (index < 0 || index >= exIds.size()) // [PENDING] return; exIds.remove (index); } else { // EVENT_ATTRIBUTE_ADD if (position == AttributeEvent.POSITION_NONE) position = exIds.size (); if (position < 0 || position > exIds.size()) // [PENDING] return; exIds.add(position, Identifier.create(info.newName)); } fireChange (impl, old, exIds); } } } public void changeCancelled(MDRChangeEvent e) { if (!parentListener.isValid) return; eventsMap.remove(e); } public void plannedChange(MDRChangeEvent event) { if (!parentListener.isValid) return; if (event instanceof AssociationEvent) { AssociationEvent assocEvent = (AssociationEvent) event; String endName = assocEvent.getEndName(); if (getEndName().equals(endName)) { EventInfo info = new EventInfo(); JavaClass jc = (JavaClass) assocEvent.getNewElement(); JavaClass old = (JavaClass) assocEvent.getOldElement(); info.index = assocEvent.getPosition(); info.newName = jc != null ? jc.getName() : null; info.oldName = old != null ? old.getName() : null; eventsMap.put(event, info); } } } class EventInfo { String newName; String oldName; int index; } } // ExceptionsListener ..................................................... static class ParametersListener implements MDRChangeListener { private ElementImpl.ElementListener parentListener; private CallableFeature javaElement; private ArrayList array = new ArrayList (); private ArrayList arrayConn = new ArrayList (); private ArrayList params = new ArrayList (); ParametersListener(ElementImpl.ElementListener parentListener) { this.parentListener = parentListener; javaElement = (CallableFeature) parentListener.javaElement; } public void initElements () { Iterator iter = javaElement.getParameters ().iterator (); for (int x = 0; iter.hasNext (); x++) { Parameter param = (Parameter) iter.next (); array.add (((CallableImpl)parentListener.getImpl ()).createParameter (param)); arrayConn.add (((CallableImpl)parentListener.getImpl ()).createParameterConn (param)); params.add (param); ((MDRChangeSource) param).addListener (this); } ((MDRChangeSource) javaElement).addListener (this); } public void removeAll () { Iterator iter = params.iterator (); while (iter.hasNext ()) { MDRChangeSource javaElem = (MDRChangeSource) iter.next (); javaElem.removeListener (this); } array.clear(); arrayConn.clear(); params.clear(); try { ((MDRChangeSource) javaElement).removeListener (this); } catch (InvalidObjectException e) { } } public int findParamIndex (RefBaseObject param) { int size = params.size (); Iterator iter = params.iterator (); for (int x = 0; x < size; x++) { RefObject obj = (RefObject) iter.next (); if (obj.equals (param)) return x; } return -1; } public void fireChange (CallableImpl impl, ArrayList oldValues, ArrayList newValues, ArrayList oldValuesConn) { MethodParameter [] oldPars = (MethodParameter []) oldValues.toArray (CallableListener.NO_PARAMETERS); MethodParameter [] newPars = (MethodParameter []) newValues.toArray (CallableListener.NO_PARAMETERS); MethodParameter [] oldParsConn = (MethodParameter []) oldValuesConn.toArray (CallableListener.NO_PARAMETERS); impl.fireChangeParameters (oldPars, newPars, oldParsConn); } public final void change(MDRChangeEvent event) { if (!parentListener.isValid) return; CallableImpl impl = (CallableImpl) parentListener.getImpl (); if (impl == null) { parentListener.remove (); return; } RefBaseObject source = (RefBaseObject) event.getSource (); if (source instanceof IsOfType) { RefObject fixed = ((AssociationEvent) event).getFixedElement (); if (fixed instanceof Parameter) { ArrayList old = (ArrayList) array.clone(); ArrayList oldConn = (ArrayList) arrayConn.clone(); int index = findParamIndex (fixed); if (index != -1) { array.set (index, ((CallableImpl)parentListener.getImpl ()).createParameter ((Parameter) fixed)); arrayConn.set (index, ((CallableImpl)parentListener.getImpl ()).createParameterConn ((Parameter) fixed)); fireChange (impl, old, array, oldConn); } } } else if (event instanceof AttributeEvent) { AttributeEvent attrEvent = (AttributeEvent) event; String attrName = attrEvent.getAttributeName (); if (source instanceof Parameter) { if (attrName.equals ("isFinal")) { // NOI18N ArrayList old = (ArrayList) array.clone (); ArrayList oldConn = (ArrayList) arrayConn.clone (); int index = findParamIndex (source); MethodParameter param = (MethodParameter) array.get (index); boolean isFinal = !param.isFinal (); param.setFinal (isFinal); param = (MethodParameter) arrayConn.get (index); param.setFinal (isFinal); fireChange (impl, old, array, oldConn); } else if (attrName.equals ("name")) { // NOI18N ArrayList old = (ArrayList) array.clone (); ArrayList oldConn = (ArrayList) arrayConn.clone (); int index = findParamIndex (source); MethodParameter param = (MethodParameter) array.get (index); String n = (String) attrEvent.getNewElement (); param.setName(n); param = (MethodParameter) arrayConn.get (index); param.setName(n); fireChange (impl, old, array, oldConn); } else if (attrName.equals("isVarArg") || attrName.equals("typeArguments")) { // NOI18N ArrayList old = (ArrayList) array.clone (); ArrayList oldConn = (ArrayList) arrayConn.clone (); int index = findParamIndex (source); MethodParameter param = ((CallableImpl)parentListener.getImpl()).createParameter ((Parameter) source); array.set(index, param); param = ((CallableImpl)parentListener.getImpl()).createParameterConn((Parameter) source); arrayConn.set(index, param); fireChange (impl, old, array, oldConn); } } else if (source instanceof CallableFeature) { if (attrName.equals ("parameters")) { // NOI18N ArrayList old = (ArrayList) array.clone (); ArrayList oldConn = (ArrayList) arrayConn.clone (); int position = attrEvent.getPosition (); if (event.isOfType (AttributeEvent.EVENT_ATTRIBUTE_REMOVE)) { RefObject oldPar = (RefObject) attrEvent.getOldElement (); if (position == AttributeEvent.POSITION_NONE) position = findParamIndex (oldPar); array.remove(position); arrayConn.remove(position); MDRChangeSource cs = (MDRChangeSource) params.remove (position); cs.removeListener (this); } else if (event.isOfType (AttributeEvent.EVENT_ATTRIBUTE_SET)) { Parameter fps = (Parameter) attrEvent.getNewElement (); array.set (position, ((CallableImpl)parentListener.getImpl()).createParameter (fps)); arrayConn.set (position, ((CallableImpl)parentListener.getImpl()).createParameterConn(fps)); MDRChangeSource cs = (MDRChangeSource) params.set (position, fps); cs.removeListener (this); ((MDRChangeSource) fps).addListener (this); } else if (event.isOfType (AttributeEvent.EVENT_ATTRIBUTE_ADD)) { Parameter fps = (Parameter) attrEvent.getNewElement (); if (position == AttributeEvent.POSITION_NONE) position = array.size (); array.add (position, ((CallableImpl)parentListener.getImpl()).createParameter (fps)); arrayConn.add (position, ((CallableImpl)parentListener.getImpl()).createParameterConn(fps)); params.add (position, fps); ((MDRChangeSource) fps).addListener (this); } fireChange (impl, old, array, oldConn); } } } } } // ParametersListener ..................................................... } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.