public WDBObject getParentObject(String superClassName, ParserAdapter scda) throws Exception { ClassDef myClass = this.getClassDef(scda); // See if its parent of this class if (myClass.getClass() == SubclassDef.class) { // See if its one of my immediate superclasses. if (parents.containsKey(superClassName)) { return scda.getObject(superClassName, ((Integer) parents.get(superClassName))); } // Not immediate superclass of me. Check my parents. Enumeration e = parents.keys(); while (e.hasMoreElements()) { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); WDBObject grandparent = parent.getParentObject(superClassName, scda); if (grandparent != null) { return grandparent; } } // Not any superClass of mine! return null; } else { return null; } }
public void removeEvaObjects( String evaName, String targetClass, SimpleNode expression, ParserAdapter scda) throws Exception { ClassDef targetClassDef = scda.getClass(targetClass); WDBObject[] matchingObjs = targetClassDef.search(expression, scda); removeEvaObjects(evaName, targetClass, matchingObjs, scda); }
public void PrintAttribute(PrintNode row, AttributePath attributePath, ParserAdapter scda) throws Exception { ClassDef myClass = this.getClassDef(scda); if (attributePath.levelsOfIndirection() <= 0) { if (attributePath.attribute.equals("*")) { for (int j = 0; j < myClass.attributes.size(); j++) { Attribute currentAttribute = (Attribute) myClass.getAttribute(j); if (currentAttribute.getClass() == DVA.class) { Object dvaValue = dvaValues.get(currentAttribute.name); PrintCell cell = new PrintCell(); cell.setOutput(String.format("%s", dvaValue)); row.addCell(cell); } } if (myClass.getClass() == SubclassDef.class) { for (int i = 0; i < ((SubclassDef) myClass).numberOfSuperClasses(); i++) { String parentClass = (String) ((SubclassDef) myClass).getSuperClass(i); Integer parentUid = (Integer) this.parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); parent.PrintAttribute(row, attributePath, scda); } } } else { Attribute currentAttribute = (Attribute) myClass.getAttribute(attributePath.attribute); Object dvaValue = getDvaValue(attributePath.attribute, scda); PrintCell cell = new PrintCell(); cell.setOutput(String.format("%s", dvaValue)); row.addCell(cell); } } else { String evaName = attributePath.getIndirection(attributePath.levelsOfIndirection() - 1); WDBObject[] objects = this.getEvaObjects(evaName, scda); ArrayList<PrintNode> branch = row.getBranch(evaName); if (objects != null && objects.length > 0) { if (branch == null) { branch = row.newBranch(evaName, objects.length); } attributePath.removeIndirection(attributePath.levelsOfIndirection() - 1); for (int i = 0; i < objects.length; i++) { objects[i].PrintAttribute(branch.get(i), attributePath, scda); } attributePath.addIndirection(evaName); } else { if (branch == null) { branch = row.newBranch(evaName, 1); myClass.padAttribute(branch.get(0), attributePath, scda); } } row.updateBranchCols(evaName); } }
public void setDvaValue(String dvaName, Object value, ParserAdapter scda) throws Exception { // See if its immediate in this class ClassDef myClass = this.getClassDef(scda); Attribute myAttribute = myClass.getAttribute(dvaName); if (myAttribute != null && myAttribute.getClass() == DVA.class) { if (value instanceof String) { this.dvaValues.put(dvaName, value); } else if (value instanceof Integer) { this.dvaValues.put(dvaName, value); } else if (value instanceof Boolean) { this.dvaValues.put(dvaName, value); } else { throw new ClassCastException( "Type verification failed: Attribute \"" + dvaName + "\" type: " + ((DVA) myAttribute).type.toString() + ", Value type: " + value.getClass().toString()); } } // Not immediate, go check parents if I'm an object of a subclass else if (myClass.getClass() == SubclassDef.class) { Enumeration e = parents.keys(); while (true) { if (parents.keySet().isEmpty()) { break; } try { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); parent.setDvaValue(dvaName, value, scda); // If we reached here, we set our value. Get out of here break; } catch (NoSuchFieldException nsfe) { // Can't find DVA going up that parent's heirarchy. Continue on to another parent if (!e.hasMoreElements()) { // No more parents to try. We are here if we exausted our parent's list and // still can't find the DVA. Throw exception throw nsfe; } } } } // value can't be found and I'm not a subclass. It doesn't exist in this heirarchy else { throw new NoSuchFieldException("Attribute \"" + dvaName + "\" is not a valid DVA"); } this.commit(scda); }
public boolean isSubclassOf(String superClassName, Adapter scda) throws Exception { // See if its one of my immediate superclasses. if (superClasses.contains(superClassName)) { return true; } // Not immediate superclass of me. Check my parents. ClassDef superClass; for (int i = 0; i < superClasses.size(); i++) { superClass = scda.getClass(((String) superClasses.get(i))); if (superClass.isSubclassOf(superClassName, scda)) { return true; } } // Not any superClass of mine! return false; }
public void printAttributeName(PrintNode row, AttributePath attributePath, Adapter scda) throws Exception { for (int j = 0; j < attributes.size(); j++) { Attribute currentAttribute = (Attribute) attributes.get(j); int attributeLength = currentAttribute.name.length() + 2; if (currentAttribute.getClass() == DVA.class && attributePath.levelsOfIndirection() <= 0) { // If the attribute we want is found or we just want everything, output if (attributePath.attribute.equals("*")) { PrintCell cell = new PrintCell(); cell.setOutput(String.format("%s", currentAttribute.name)); row.addCell(cell); } else if (attributePath.attribute.equals(currentAttribute.name)) { PrintCell cell = new PrintCell(); cell.setOutput(String.format("%s", currentAttribute.name)); row.addCell(cell); return; } } if (currentAttribute.getClass() == EVA.class && attributePath.levelsOfIndirection() > 0) { String evaName = attributePath.getIndirection(attributePath.levelsOfIndirection() - 1); if (evaName.equals(currentAttribute.name)) { ClassDef targetClass = scda.getClass(((EVA) currentAttribute).baseClassName); attributePath.removeIndirection(attributePath.levelsOfIndirection() - 1); targetClass.printAttributeName(row, attributePath, scda); attributePath.addIndirection(evaName); return; } } } // Got here if we didn't get what we need in this class int i = 0; while (i < superClasses.size()) { try { ClassDef superClass = scda.getClass(((String) superClasses.get(i))); superClass.printAttributeName(row, attributePath, scda); i++; } catch (NoSuchFieldException nsfe) { if (i < superClasses.size()) { i++; } else { throw nsfe; } } } }
public void padAttribute(PrintNode row, AttributePath attributePath, Adapter scda) throws Exception { for (int j = 0; j < attributes.size(); j++) { Attribute currentAttribute = (Attribute) attributes.get(j); int attributeLength = currentAttribute.name.length(); if (currentAttribute.getClass() == DVA.class && attributePath.levelsOfIndirection() <= 0) { // If the attribute we want is found or we just want everything, output if (attributePath.attribute.equals("*")) { PrintCell cell = new PrintCell(); cell.setOutput(String.format("")); row.addCell(cell); } else if (attributePath.attribute.equals(currentAttribute.name)) { PrintCell cell = new PrintCell(); cell.setOutput(String.format("")); row.addCell(cell); return; } } if (currentAttribute.getClass() == EVA.class && attributePath.levelsOfIndirection() > 0) { String evaName = attributePath.getIndirection(attributePath.levelsOfIndirection() - 1); if (evaName.equals(currentAttribute.name)) { ClassDef targetClass = scda.getClass(((EVA) currentAttribute).baseClassName); attributePath.removeIndirection(attributePath.levelsOfIndirection() - 1); targetClass.padAttribute(row, attributePath, scda); attributePath.addIndirection(evaName); return; } } } if (!(attributePath.attribute.equals("*") && attributePath.levelsOfIndirection() <= 0)) { // If we got here and we weren't trying to output all the attributes, we didn't find the // requested attribute. if (this.getClass() == SubclassDef.class) { for (int i = 0; i < ((SubclassDef) this).numberOfSuperClasses(); i++) { ClassDef parentClass = scda.getClass(((SubclassDef) this).getSuperClass(i)); parentClass.padAttribute(row, attributePath, scda); } } else { throw new NoSuchFieldException( "Attribute \"" + attributePath.attribute + "\" is not a valid DVA"); } } }
public WDBObject newInstance(WDBObject baseParent, Adapter scda) throws Exception { Integer newUid = new Integer(Math.abs((new UID()).hashCode())); WDBObject newObject = new WDBObject( new Hashtable<String, Integer>(), new Hashtable<String, Integer>(), new Hashtable<String, Object>(), new Hashtable<String, Object>(), this.name, newUid); for (int i = 0; i < this.superClasses.size(); i++) { ClassDef superClass = scda.getClass((String) this.superClasses.get(i)); WDBObject parent; if (baseParent == null || !superClass.name.equals(baseParent.getClassName())) { if (superClass.getClass() == SubclassDef.class) { // If this super class is another subclass, then create a new instance of one of those // with this object as the child and the parent we want to attach to parent = superClass.newInstance(baseParent, scda); } else { // If this super class is a base class, then create a new isntance but don't pass the // parent we want to attach since its a base class parent = superClass.newInstance(null, scda); } } else { // The base parent is my immediate parent parent = baseParent; } WDBObject childObject = parent.getChildObject(this.name, scda); if (childObject != null) { // Parent alreadly extended to this class, just return the child instance return childObject; } parent.addChildObject(newObject); parent.commit(scda); newObject.addParentObject(parent); } this.addInstance(newUid); this.commit(scda); return newObject; }
public Object getDvaValue(String dvaName, ParserAdapter scda) throws Exception { Object value = null; // See if its immediate in this class ClassDef myClass = this.getClassDef(scda); Attribute myAttribute = myClass.getAttribute(dvaName); if (myAttribute != null && myAttribute.getClass() == DVA.class) { value = this.dvaValues.get(dvaName); } // Not immediate, go check parents if I'm an object of a subclass else if (myClass.getClass() == SubclassDef.class) { Enumeration e = parents.keys(); while (true) { try { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); value = parent.getDvaValue(dvaName, scda); // If we reached here, we got our value. Get out of here break; } catch (NoSuchFieldException nsfe) { // Can't find DVA going up that parent's heirarchy. Continue on to another parent if (!e.hasMoreElements()) { // No more parents to try. We are here if we exausted our parent's list and // still can't find the DVA. Throw exception throw nsfe; } } } } // value can't be found and I'm not a subclass. It doesn't exist in this heirarchy else { throw new NoSuchFieldException("Attribute \"" + dvaName + "\" is not a valid DVA"); } return value; }
public WDBObject getBaseObject(ParserAdapter scda) throws Exception { ClassDef myClass = this.getClassDef(scda); // See if its parent of this class if (myClass.getClass() == SubclassDef.class) { // Check my parents. Enumeration e = parents.keys(); while (e.hasMoreElements()) { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); WDBObject grandparent = parent.getBaseObject(scda); if (grandparent != null) { return grandparent; } } // Not any superClass of mine! return null; } else if (myClass.getClass() == ClassDef.class) { return this; } else { return null; } }
/* private void addEvaInverse(EVA ownerEva, ClassDef ownerEvaClass, WDBObject ownerEvaObject, ParserAdapter scda) throws Exception { //Try to see if other class's inverse EVA is declared on my side ClassDef myClass = this.getClassDef(scda); Attribute myAttribute = myClass.getAttribute(ownerEva.inverseEVA); if(myAttribute != null && myAttribute.getClass() == EVA.class) { //Oh it is, good. Use the declared settings if(((EVA)myAttribute).cardinality == EVA.MULTIVALUED) { ArrayList targetObjectList = ((ArrayList)this.evaObjects.get(myAttribute.name)); if(targetObjectList == null) { targetObjectList = new ArrayList(); } targetObjectList.add(ownerEvaObject.getUid()); this.evaObjects.put(myAttribute.name, targetObjectList); } else if(((EVA)myAttribute).cardinality == EVA.SINGLEVALUED) { //For singlevalued EVAs, just put the UID as the value; this.evaObjects.put(myAttribute.name, ownerEvaObject.getUid()); } else { throw new NoSuchFieldException("Attribute \"" + myAttribute.name + "\" uses a invalid cardinality"); } } else { throw new Exception("Implication of target class inverse EVAs is not implemented"); //The inverse EVA is not defined in this class or there is no inverse EVA specified //We have to infer the cardinality of our inverse based on the cardinality EVA from the owner's class if(ownerEva.cardinality == EVA.SINGLEVALUED) { //Imply MV UNIQUE if(myAttribute != null) { ArrayList targetObjectList = ((ArrayList)this.evaObjects.get(myAttribute.name)); if(targetObjectList == null) { targetObjectList = new ArrayList(); } targetObjectList.add(ownerEvaObject.getUid()); } } } this.commit(scda); } */ public WDBObject[] getEvaObjects(String evaName, ParserAdapter scda) throws Exception { ClassDef myClass = this.getClassDef(scda); Attribute myAttribute = myClass.getAttribute(evaName); WDBObject[] evaObjects = new WDBObject[0]; if (myAttribute != null && myAttribute.getClass() == EVA.class) { if (((EVA) myAttribute).cardinality.equals(EVA.MULTIVALUED)) { ArrayList<Object> targetObjectList = ((ArrayList) this.evaObjects.get(evaName)); ArrayList<WDBObject> targetObjects = new ArrayList<WDBObject>(); if (targetObjectList != null) { for (int i = 0; i < targetObjectList.size(); i++) { String[] targetKey = ((String) targetObjectList.get(i)).split(":"); String targetClass = targetKey[0]; Integer targetUid = Integer.valueOf(targetKey[1]); WDBObject targetObject = scda.getObject(targetClass, targetUid); targetObjects.add(targetObject); } evaObjects = ((WDBObject[]) targetObjects.toArray(evaObjects)); } } else if (((EVA) myAttribute).cardinality.equals(EVA.SINGLEVALUED)) { if (this.evaObjects.get(evaName) != null) { String[] targetKey = ((String) this.evaObjects.get(evaName)).split(":"); String targetClass = targetKey[0]; Integer targetUid = Integer.valueOf(targetKey[1]); WDBObject targetObject = scda.getObject(targetClass, targetUid); if (targetObject != null) { WDBObject[] targetObjs = {((WDBObject) targetObject)}; evaObjects = targetObjs; } } } else { throw new NoSuchFieldException("Attribute \"" + evaName + "\" uses a invalid cardinality"); } } else if (myClass.getClass() == SubclassDef.class) { Enumeration e = parents.keys(); while (true) { try { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); return parent.getEvaObjects(evaName, scda); // If we reached here, we get our value. Get out of here // break; } catch (NoSuchFieldException nsfe) { // Can't find DVA going up that parent's heirarchy. Continue on to another parent if (!e.hasMoreElements()) { // No more parents to try. We are here if we exausted our parent's list and // still can't find the DVA. Throw exception throw nsfe; } } } } // value can't be found and I'm not a subclass. It doesn't exist in this heirarchy else { throw new NoSuchFieldException("Attribute \"" + evaName + "\" is not a valid EVA"); } return evaObjects; }
public void removeEvaObjects( String evaName, String targetClass, WDBObject[] targetObjects, ParserAdapter scda) throws Exception { // Don't do anything if the target objects to remove is null if (targetObjects != null) { ClassDef myClass = this.getClassDef(scda); Attribute myAttribute = myClass.getAttribute(evaName); if (myAttribute != null && myAttribute.getClass() == EVA.class) { ClassDef targetClassDef = scda.getClass(targetClass); if (targetClassDef.name.equals(((EVA) myAttribute).baseClassName) || targetClassDef.isSubclassOf((((EVA) myAttribute).baseClassName), scda)) { ClassDef baseClassDef = scda.getClass(((EVA) myAttribute).baseClassName); WDBObject baseObject; for (int i = 0; i < targetObjects.length; i++) { // See if we can remove it from our end first if (this.removeEvaObject((EVA) myAttribute, targetObjects[i], scda)) { // Get the object that belongs to the base class of the EVA if ((((EVA) myAttribute).baseClassName).equals(targetClassDef.name)) { baseObject = targetObjects[i]; } else { baseObject = targetObjects[i].getParentObject((((EVA) myAttribute).baseClassName), scda); } // Get the inverse EVA, if there is one Attribute inverseAttribute = baseClassDef.getAttribute(((EVA) myAttribute).inverseEVA); // Put myself as a reference in the target's EVA if (inverseAttribute != null && inverseAttribute.getClass() == EVA.class) { baseObject.removeEvaObject((EVA) inverseAttribute, this, scda); } else { throw new Exception("Implication of target class inverse EVAs is not implemented"); } // Update the object baseObject.commit(scda); } } } } // Not immediate, go check parents if I'm an object of a subclass else if (myClass.getClass() == SubclassDef.class) { Enumeration e = parents.keys(); while (true) { try { String parentClass = (String) e.nextElement(); Integer parentUid = (Integer) parents.get(parentClass); WDBObject parent = scda.getObject(parentClass, parentUid); parent.removeEvaObjects(evaName, targetClass, targetObjects, scda); // If we reached here, we set our value. Get out of here break; } catch (NoSuchFieldException nsfe) { // Can't find DVA going up that parent's heirarchy. Continue on to another parent if (!e.hasMoreElements()) { // No more parents to try. We are here if we exausted our parent's list and // still can't find the DVA. Throw exception throw nsfe; } } } } // value can't be found and I'm not a subclass. It doesn't exist in this heirarchy else { throw new NoSuchFieldException("Attribute \"" + evaName + "\" is not a valid EVA"); } this.commit(scda); } }
void handleClassAnnotation(ClassDef classDef) { Set<? extends Annotation> aSet = classDef.getAnnotations(); if (aSet == null || aSet.isEmpty()) return; List<Tag> tags = handleAnnotation(aSet, classDef.getType()); if (tags == null) return; InnerClassAttribute ica = null; for (Tag t : tags) if (t != null) { if (t instanceof InnerClassTag) { if (ica == null) { // Do we already have an InnerClassAttribute? ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute"); // If not, create one if (ica == null) { ica = new InnerClassAttribute(); clazz.addTag(ica); } } ica.add((InnerClassTag) t); } else if (t instanceof VisibilityAnnotationTag) { // If a dalvik/annotation/AnnotationDefault tag is present // in a class, its AnnotationElements must be propagated // to methods through the creation of new AnnotationDefaultTag. VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t; for (AnnotationTag a : vt.getAnnotations()) { if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) { for (AnnotationElem ae : a.getElems()) { if (ae instanceof AnnotationAnnotationElem) { AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae; AnnotationTag at = aae.getValue(); // extract default elements Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>(); for (AnnotationElem aelem : at.getElems()) { defaults.put(aelem.getName(), aelem); } // create default tags containing default elements // and add tags on methods for (SootMethod sm : clazz.getMethods()) { String methodName = sm.getName(); if (defaults.containsKey(methodName)) { AnnotationElem e = defaults.get(methodName); // Okay, the name is the same, but is it actually the same type? Type annotationType = getSootType(e); boolean isCorrectType = false; if (annotationType == null) { // we do not know the type of the annotation, so we guess it's the correct // type. isCorrectType = true; } else { if (annotationType.equals(sm.getReturnType())) { isCorrectType = true; } else if (annotationType.equals(ARRAY_TYPE)) { if (sm.getReturnType() instanceof ArrayType) isCorrectType = true; } } if (isCorrectType && sm.getParameterCount() == 0) { e.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(e); sm.addTag(d); // In case there is more than one matching method, we only use the first one defaults.remove(sm.getName()); } } } for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) { // We were not able to find a matching method for the tag, because the return // signature // does not match SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey()); AnnotationElem element = leftOverEntry.getValue(); if (found != null) { element.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(element); found.addTag(d); } } } } } } if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE)) clazz.addTag(vt); } else { clazz.addTag(t); } Debug.printDbg("add class annotation: ", t, " type: ", t.getClass()); } }
public ClassDef getBaseClass(Adapter scda) throws Exception { // Assume all of our superclasses go back to the same base class alreadly ClassDef superClass; superClass = scda.getClass(((String) superClasses.get(0))); return superClass.getBaseClass(scda); }