/** * Check that child components are of types compatible with the collection item-type. This method * may call itself recursively to process the children of child components which do not themselves * set a type. * * @param vctx validation context * @param type collection item type * @param children list of child components to be checked */ private void checkCollectionChildren(ValidationContext vctx, IClass type, ArrayList children) { for (int i = 0; i < children.size(); i++) { ElementBase child = (ElementBase) children.get(i); if (!vctx.isSkipped(child)) { boolean expand = true; if (child instanceof IComponent) { IComponent comp = (IComponent) child; IClass ctype = comp.getType(); expand = false; if (comp instanceof ContainerElementBase) { ContainerElementBase contain = (ContainerElementBase) comp; if (contain.hasObject()) { ctype = contain.getObjectType(); } else { expand = true; } } if (!expand) { if (!ctype.isAssignable(type)) { vctx.addFatal( "References to collection items must " + "use compatible types: " + ctype.getName() + " cannot be used as " + type.getName(), child); } } } if (expand && child instanceof NestingElementBase) { checkCollectionChildren(vctx, type, ((NestingElementBase) child).children()); } } } }
@Override public IField getField(Atom name) { if (fieldMap.containsKey(name)) { return fieldMap.get(name); } else { List<IField> fields = findDeclaredField(name); if (!fields.isEmpty()) { if (fields.size() == 1) { IField f = fields.iterator().next(); fieldMap.put(name, f); return f; } else { throw new IllegalStateException("multiple fields with name " + name); } } else if ((superClass = getSuperclass()) != null) { IField f = superClass.getField(name); if (f != null) { fieldMap.put(name, f); return f; } } // try superinterfaces for (IClass i : getAllImplementedInterfaces()) { IField f = i.getField(name); if (f != null) { fieldMap.put(name, f); return f; } } } return null; }
private IClass findClass(String s) { for (IClass c : m.getClasses()) { if (c.getName().equals(s)) { return c; } } return null; }
/** * Check children of ordered collection for consistency. In an input binding each child element * must use a different qualified name from the preceding child element. In an output binding each * child element must define a different type from the preceding child element, or the preceding * child element must supply a test method to allow checking when that element should be generated * for an object. * * @param vctx validation context * @param children list of child components */ private void checkOrderedChildren(ValidationContext vctx, ArrayList children) { IComponent prior = null; for (int i = 0; i < children.size(); i++) { ElementBase child = (ElementBase) children.get(i); if (child instanceof IComponent && !vctx.isSkipped(child)) { IComponent comp = (IComponent) child; if (vctx.isInBinding() && !comp.hasName()) { vctx.addFatal( "Child components of collection must " + "define element name for unmarshalling", comp); } if (prior == null) { prior = comp; } else { if (vctx.isInBinding()) { // make sure names are different String uri = comp.getUri(); String cname = comp.getName(); String pname = prior.getName(); if (cname != null && pname != null && cname.equals(pname) && ((uri == null && prior.getUri() == null) || (uri != null && uri.equals(prior.getUri())))) { vctx.addError( "Successive elements of collection " + "cannot use duplicate names for unmarshalling", comp); } } if (vctx.isOutBinding()) { // make sure types differ or test method supplied IClass type = comp.getType(); if (type.isAssignable(prior.getType())) { IClassItem test = null; if (prior instanceof ValueElement) { test = ((ValueElement) prior).getTest(); } else if (prior instanceof StructureElementBase) { test = ((StructureElementBase) prior).getTest(); } if (test == null) { vctx.addError( "Collection component must " + "specify a test-method to distinguish " + "from next component of compatible type " + "for marshalling", comp); } } } } } } }
/* * @see com.ibm.wala.classLoader.IClass#getAllStaticFields() */ @Override public Collection<IField> getAllStaticFields() { Collection<IField> result = new LinkedList<IField>(getDeclaredStaticFields()); IClass s = getSuperclass(); while (s != null) { result.addAll(s.getDeclaredStaticFields()); s = s.getSuperclass(); } return result; }
/** * Get best binding component for class. Finds the component based on a fully qualified class * name. If a specific component for the actual class is not found (either in this or a containing * level) this returns the most specific superclass component. * * @param clas information for target class * @return binding component definition for class, or <code>null</code> if none found */ public ElementBase getMostSpecificComponent(IClass clas) { ElementBase comp = getSpecificComponent(clas.getName()); while (comp == null) { IClass sclas = clas.getSuperClass(); if (sclas == null) { break; } clas = sclas; comp = getSpecificComponent(clas.getName()); } return comp; }
/* * @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.types.Selector) */ @Override public IMethod getMethod(Selector selector) { try { computeMethodMapIfNeeded(); } catch (InvalidClassFileException e1) { e1.printStackTrace(); Assertions.UNREACHABLE(); } // my methods + cached parent stuff IMethod result = methodMap.get(selector); if (result != null) { return result; } if (inheritCache != null) { result = inheritCache.get(selector); if (result != null) { return result; } } // check parent, caching if found if (!selector.equals(MethodReference.clinitSelector) && !selector.equals(MethodReference.initSelector)) { IClass superclass = getSuperclass(); if (superclass != null) { IMethod inherit = superclass.getMethod(selector); if (inherit != null) { if (inheritCache == null) { inheritCache = new BimodalMap<Selector, IMethod>(5); } inheritCache.put(selector, inherit); return inherit; } } } // didn't find it yet. special logic for interfaces if (isInterface() || isAbstract()) { final Iterator<IClass> it = getAllImplementedInterfaces().iterator(); // try each superinterface while (it.hasNext()) { IClass k = it.next(); result = k.getMethod(selector); if (result != null) { return result; } } } return null; }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((declaringClass == null) ? 0 : declaringClass.hashCode()); result = prime * result + ((method == null) ? 0 : method.hashCode()); return result; }
/** * Checks if a class is compatible with one or more components. If a specific component for the * actual class is not found (either in this or a containing level) this checks for components * that handle subclasses or implementations of the class. * * @param clas information for target class * @return <code>true</code> if compatible type, <code>false</code> if not */ public boolean isCompatibleType(IClass clas) { if (m_compatibleTypeSet.contains(clas.getName())) { return true; } else if (m_outerContext != null) { return m_outerContext.isCompatibleType(clas); } else { return false; } }
/** * Add typed component to set defined at this level. This associated the component with the type * for class hierarchy-based lookups. * * @param type type name to be associated with component * @param comp definition component to be added * @param vctx validation context in use */ public void addTypedComponent(IClass clas, ElementBase comp, ValidationContext vctx) { String type = clas.getName(); if (m_typeToComponentMap.put(type, comp) == null) { // new type, add all interfaces and supertypes to compatible set String[] interfaces = clas.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { m_compatibleTypeSet.add(interfaces[i]); } IClass sclas = clas; do { m_compatibleTypeSet.add(sclas.getName()); } while ((sclas = sclas.getSuperClass()) != null); } else { vctx.addError("Duplicate conversion defined for type " + type, comp); } }
/* * @see com.ibm.wala.classLoader.IClass#getSuperclass() */ @Override public IClass getSuperclass() { IClass elt = getElementClass(); assert getReference().getArrayElementType().isPrimitiveType() || elt != null; // super is Ljava/lang/Object in two cases: // 1) [Ljava/lang/Object // 2) [? for primitive arrays (null from getElementClass) if (elt == null || elt.getReference() == getClassLoader().getLanguage().getRootType()) { return loader.lookupClass(getClassLoader().getLanguage().getRootType().getName()); } // else it is array of super of element type (yuck) else { TypeReference eltSuperRef = elt.getSuperclass().getReference(); TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef); return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName()); } }
@Override public IField getField(Atom name, TypeName type) { boolean unresolved = false; try { // typically, there will be at most one field with the name IField field = getField(name); if (field != null && field.getFieldTypeReference().getName().equals(type)) { return field; } else { unresolved = true; } } catch (IllegalStateException e) { assert e.getMessage().startsWith("multiple fields with"); unresolved = true; } if (unresolved) { // multiple fields. look through all of them and see if any have the appropriate type List<IField> fields = findDeclaredField(name); for (IField f : fields) { if (f.getFieldTypeReference().getName().equals(type)) { return f; } } // check superclass if (getSuperclass() != null) { IField f = superClass.getField(name, type); if (f != null) { return f; } } // try superinterfaces for (IClass i : getAllImplementedInterfaces()) { IField f = i.getField(name, type); if (f != null) { return f; } } } return null; }
/** @return Collection of IClasses, representing the interfaces this class implements. */ protected Collection<IClass> computeAllInterfacesAsCollection() { Collection<? extends IClass> c = getDirectInterfaces(); Set<IClass> result = HashSetFactory.make(); for (Iterator<? extends IClass> it = c.iterator(); it.hasNext(); ) { IClass klass = it.next(); if (klass.isInterface()) { result.add(klass); } else { Warnings.add(ClassHierarchyWarning.create("expected an interface " + klass)); } } // at this point result holds all interfaces the class directly extends. // now expand to a fixed point. Set<IClass> last = null; do { last = HashSetFactory.make(result); for (IClass i : last) { result.addAll(i.getDirectInterfaces()); } } while (last.size() < result.size()); // now add any interfaces implemented by the super class IClass sup = null; sup = getSuperclass(); if (sup != null) { result.addAll(sup.getAllImplementedInterfaces()); } return result; }
/* * @see com.ibm.wala.classLoader.IClass#getAllMethods() */ @Override public Collection<IMethod> getAllMethods() { Collection<IMethod> result = new LinkedList<IMethod>(); Iterator<IMethod> declaredMethods = getDeclaredMethods().iterator(); while (declaredMethods.hasNext()) { result.add(declaredMethods.next()); } if (isInterface()) { for (IClass i : getDirectInterfaces()) { result.addAll(i.getAllMethods()); } } IClass s = getSuperclass(); while (s != null) { Iterator<IMethod> superDeclaredMethods = s.getDeclaredMethods().iterator(); while (superDeclaredMethods.hasNext()) { result.add(superDeclaredMethods.next()); } s = s.getSuperclass(); } return result; }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final SyntheticMethod other = (SyntheticMethod) obj; if (declaringClass == null) { if (other.declaringClass != null) return false; } else if (!declaringClass.equals(other.declaringClass)) return false; if (method == null) { if (other.method != null) return false; } else if (!method.equals(other.method)) return false; return true; }
private void initTestClassesAndInstances() { // // TestClasses and instances // Object[] instances = getInstances(false); for (Object instance : instances) { if (instance instanceof ITest) { testName = ((ITest) instance).getTestName(); break; } } if (testName == null) { testName = iClass.getTestName(); } }
private void init( IClass cls, ITestMethodFinder testMethodFinder, IAnnotationFinder annotationFinder, XmlTest xmlTest, XmlClass xmlClass) { log(3, "Creating TestClass for " + cls); iClass = cls; m_testClass = cls.getRealClass(); this.xmlTest = xmlTest; this.xmlClass = xmlClass; this.testMethodFinder = testMethodFinder; this.annotationFinder = annotationFinder; initTestClassesAndInstances(); initMethods(); }
/** * Create the test methods that belong to this class (rejects all those that belong to a different * class). */ private ITestNGMethod[] createTestMethods(ITestNGMethod[] methods) { List<ITestNGMethod> vResult = Lists.newArrayList(); for (ITestNGMethod tm : methods) { ConstructorOrMethod m = tm.getConstructorOrMethod(); if (m.getDeclaringClass().isAssignableFrom(m_testClass)) { for (Object o : iClass.getInstances(false)) { log(4, "Adding method " + tm + " on TestClass " + m_testClass); vResult.add( new TestNGMethod( /* tm.getRealClass(), */ m.getMethod(), annotationFinder, xmlTest, o)); } } else { log(4, "Rejecting method " + tm + " for TestClass " + m_testClass); } } return vResult.toArray(new ITestNGMethod[vResult.size()]); }
/* (non-Javadoc) * @see org.jibx.binding.model.ElementBase#prevalidate(org.jibx.binding.model.ValidationContext) */ public void prevalidate(ValidationContext vctx) { // first process attributes and check for errors super.prevalidate(vctx); if (!vctx.isSkipped(this)) { // check for ignored attributes if (isAllowRepeats()) { vctx.addWarning("'allow-repeats' attribute ignored on collection"); } if (isChoice()) { vctx.addWarning("'choice' attribute ignored on collection"); } // get the actual collection type and item type IClass clas = getType(); if (clas == null) { clas = vctx.getContextObject().getObjectType(); } String tname = m_itemTypeName; if (tname == null) { String ctype = clas.getName(); if (ctype.endsWith("[]")) { tname = ctype.substring(0, ctype.length() - 2); } else { tname = "java.lang.Object"; } } m_itemTypeClass = vctx.getClassInfo(tname); if (m_itemTypeClass == null) { vctx.addFatal("Can't find class " + tname); } // handle input and output bindings separately if (vctx.isInBinding()) { // check store techniques String sname = m_storeMethodName; String aname = m_addMethodName; if (sname != null && aname != null) { vctx.addWarning("Both store-method and add-method " + "supplied; using add-method"); sname = null; } // set defaults based on collection type if needed if (sname == null && aname == null) { if (clas.isSuperclass("java.util.ArrayList") || clas.isSuperclass("java.util.Vector") || clas.isImplements("Ljava/util/Collection;")) { aname = "add"; } else if (!clas.getName().endsWith("[]")) { vctx.addError("Need store-method or add-method for " + "input binding"); } } // find the actual method information if (sname != null) { m_storeMethodItem = clas.getBestMethod(sname, null, new String[] {"int", tname}); if (m_storeMethodItem == null) { vctx.addError("store-method " + sname + " not found in class " + clas.getName()); } } if (aname != null) { m_addMethodItem = clas.getBestMethod(aname, null, new String[] {tname}); if (m_addMethodItem == null) { vctx.addError("add-method " + aname + " not found in class " + clas.getName()); } } } if (vctx.isOutBinding()) { // precheck load techniques String lname = m_loadMethodName; String sname = m_sizeMethodName; String iname = m_iterMethodName; if (lname == null) { if (sname != null) { vctx.addWarning("size-method requires load-method; " + "ignoring supplied size-method"); sname = null; } } else { if (sname == null) { vctx.addWarning("load-method requires " + "size-method; ignoring supplied load-method"); lname = null; } else { if (iname != null) { vctx.addWarning("Both load-method and " + "iter-method supplied; using load-method"); iname = null; } } } // set defaults based on collection type if needed if (lname == null && iname == null) { if (clas.isSuperclass("java.util.ArrayList") || clas.isSuperclass("java.util.Vector")) { lname = "get"; sname = "size"; } else if (clas.isImplements("Ljava/util/Collection;")) { iname = "iterator"; } } // postcheck load techniques with defaults set if (lname == null) { if (iname == null && !clas.getName().endsWith("[]")) { vctx.addError( "Need load-method and size-method, or " + "iter-method, for output binding"); } } else { if (sname == null && iname == null) { vctx.addError( "Need load-method and size-method," + " or iter-method, for output binding"); } } // find the actual method information if (lname != null) { m_loadMethodItem = clas.getBestMethod(lname, tname, new String[] {"int"}); if (m_loadMethodItem == null) { vctx.addError("load-method " + lname + " not found in class " + clas.getName()); } } if (iname != null) { m_iterMethodItem = clas.getBestMethod(iname, "java.util.Iterator", new String[0]); if (m_iterMethodItem == null) { vctx.addError("iter-method " + iname + " not found in class " + clas.getName()); } } } } }
@Override public void parse(IParserManager pm, IToken token) throws SyntaxError { int type = token.type(); if (this.isInMode(MODIFIERS)) { int i = 0; if ((i = ModifierTypes.CLASS.parse(type)) != -1) { this.theClass.addModifier(i); return; } if ((i = ModifierTypes.CLASS_TYPE.parse(type)) != -1) { this.theClass.addModifier(i); this.theClass.setMetadata( IClass.getClassMetadata(this.theClass, this.theClass.getModifiers())); this.mode = NAME; return; } if (token.nameValue() == Name.at) { Annotation annotation = new Annotation(token.raw()); this.theClass.addAnnotation(annotation); pm.pushParser(new AnnotationParser(annotation)); return; } } if (this.isInMode(NAME)) { if (ParserUtil.isIdentifier(type)) { this.theClass.setPosition(token.raw()); this.theClass.setName(token.nameValue()); this.classList.addClass(this.theClass); this.mode = PARAMETERS | GENERICS | EXTENDS | IMPLEMENTS | BODY; return; } throw new SyntaxError(token, "Invalid Class Declaration - Name expected"); } if (this.isInMode(PARAMETERS)) { if (type == Symbols.OPEN_PARENTHESIS) { pm.pushParser(new ParameterListParser(this.theClass)); this.mode = PARAMETERS_END; return; } } if (this.isInMode(PARAMETERS_END)) { this.mode = GENERICS | EXTENDS | IMPLEMENTS | BODY; if (type == Symbols.CLOSE_PARENTHESIS) { return; } throw new SyntaxError(token, "Invalid Class Parameter List - ')' expected", true); } if (this.isInMode(GENERICS)) { if (type == Symbols.OPEN_SQUARE_BRACKET) { pm.pushParser(new TypeVariableListParser(this.theClass)); this.theClass.setGeneric(); this.mode = GENERICS_END; return; } } if (this.isInMode(GENERICS_END)) { this.mode = PARAMETERS | EXTENDS | IMPLEMENTS | BODY; if (type == Symbols.CLOSE_SQUARE_BRACKET) { return; } throw new SyntaxError(token, "Invalid Generic Type Variable List - ']' expected", true); } if (this.isInMode(EXTENDS)) { if (type == Keywords.EXTENDS) { if (this.theClass.hasModifier(Modifiers.INTERFACE_CLASS)) { pm.pushParser(new TypeListParser(this)); this.mode = BODY; return; } pm.pushParser(new TypeParser(this)); this.mode = IMPLEMENTS | BODY; return; } } if (this.isInMode(IMPLEMENTS)) { if (type == Keywords.IMPLEMENTS) { pm.pushParser(new TypeListParser(this)); this.mode = BODY; if (this.theClass.hasModifier(Modifiers.INTERFACE_CLASS)) { throw new SyntaxError( token, "Interfaces cannot implement other interfaces - Use 'extends' instead"); } return; } } if (this.isInMode(BODY)) { if (type == Symbols.OPEN_CURLY_BRACKET) { IClassBody body = new ClassBody(this.theClass); this.theClass.setBody(body); pm.pushParser(new ClassBodyParser(this.theClass, body)); this.mode = BODY_END; return; } if (ParserUtil.isTerminator(type)) { if (token.isInferred()) { int nextType = token.next().type(); switch (nextType) { case Keywords.EXTENDS: this.mode = EXTENDS; return; case Keywords.IMPLEMENTS: this.mode = IMPLEMENTS; return; case Symbols.OPEN_SQUARE_BRACKET: this.mode = GENERICS; return; case Symbols.OPEN_PARENTHESIS: this.mode = PARAMETERS; return; } } pm.popParser(); this.theClass.expandPosition(token); return; } throw new SyntaxError(token, "Invalid Class Declaration - '{' or ';' expected", true); } if (this.isInMode(BODY_END)) { if (type == Symbols.CLOSE_CURLY_BRACKET) { pm.popParser(); this.theClass.expandPosition(token); return; } throw new SyntaxError(token, "Invalid Class Declaration - '}' expected", true); } }
private boolean checkForAdapter(String s, Set<IRelation> filtered) { IClass adapter = findClass(s); IClass adaptee = null; IClass target = null; for (IRelation r : filtered) { if (r.getSrc().equals(s) && r.getType().equals("ASSOCIATION")) { adaptee = findClass(r.getDest()); } if (r.getSrc().equals(s) && r.getType().equals("IMPLEMENTS")) { target = findClass(r.getDest()); } } if (adaptee == null || target == null) return false; for (IField f : adapter.getFields()) { if (f.getType().equals(adaptee.getName())) { adapter.setStereotype("adapter"); adaptee.setStereotype("adaptee"); target.setStereotype("target"); adapter.setPattern("ADAPTER"); adaptee.setPattern("ADAPTER"); target.setPattern("ADAPTER"); for (IRelation r : m.getRelations()) { if (r.getSrc().equals(s) && r.getDest().equals(adaptee.getName()) && r.getType().equals("ASSOCIATION")) { r.setLabel("adapts"); } } return true; } } return false; }
@Override public long[] getInstanceHashCodes() { return iClass.getInstanceHashCodes(); }
@Deprecated @Override public int getInstanceCount() { return iClass.getInstanceCount(); }
@Override public void addInstance(Object instance) { iClass.addInstance(instance); }
private void initMethods() { ITestNGMethod[] methods = testMethodFinder.getTestMethods(m_testClass, xmlTest); m_testMethods = createTestMethods(methods); for (Object instance : iClass.getInstances(false)) { m_beforeSuiteMethods = ConfigurationMethod.createSuiteConfigurationMethods( testMethodFinder.getBeforeSuiteMethods(m_testClass), annotationFinder, true, instance); m_afterSuiteMethods = ConfigurationMethod.createSuiteConfigurationMethods( testMethodFinder.getAfterSuiteMethods(m_testClass), annotationFinder, false, instance); m_beforeTestConfMethods = ConfigurationMethod.createTestConfigurationMethods( testMethodFinder.getBeforeTestConfigurationMethods(m_testClass), annotationFinder, true, instance); m_afterTestConfMethods = ConfigurationMethod.createTestConfigurationMethods( testMethodFinder.getAfterTestConfigurationMethods(m_testClass), annotationFinder, false, instance); m_beforeClassMethods = ConfigurationMethod.createClassConfigurationMethods( testMethodFinder.getBeforeClassMethods(m_testClass), annotationFinder, true, instance); m_afterClassMethods = ConfigurationMethod.createClassConfigurationMethods( testMethodFinder.getAfterClassMethods(m_testClass), annotationFinder, false, instance); m_beforeGroupsMethods = ConfigurationMethod.createBeforeConfigurationMethods( testMethodFinder.getBeforeGroupsConfigurationMethods(m_testClass), annotationFinder, true, instance); m_afterGroupsMethods = ConfigurationMethod.createAfterConfigurationMethods( testMethodFinder.getAfterGroupsConfigurationMethods(m_testClass), annotationFinder, false, instance); m_beforeTestMethods = ConfigurationMethod.createTestMethodConfigurationMethods( testMethodFinder.getBeforeTestMethods(m_testClass), annotationFinder, true, instance); m_afterTestMethods = ConfigurationMethod.createTestMethodConfigurationMethods( testMethodFinder.getAfterTestMethods(m_testClass), annotationFinder, false, instance); } }
@Override public Object[] getInstances(boolean create) { return iClass.getInstances(create); }