/** * Do a recursive find and replace of objects pointed to by this object. * * @since v1.0 * @param objectText Canonical string representation of the portion we want to replace. * @param replacement object we want to replace this portion with. A replacement will occur if a * portion of the structure is found with a match of the encoded text with objectText and with * the same class as replacement. * @param matchSubstring is true if we want to match objectText as a substring of the encoded * target text. (i.e. an object is a candidate for replacement if objectText is a substring of * candidate.encode() && candidate.class.equals(replacement.class) otherwise the match test is * an equality test.) */ public void replace(String objectText, GenericObjectList replacement, boolean matchSubstring) throws IllegalArgumentException { if (objectText == null || replacement == null) { throw new IllegalArgumentException("null argument!"); } Class replacementClass = replacement.getClass(); Class myclass = getClass(); Field[] fields = myclass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; Class fieldType = f.getType(); if (!getClassFromName(SIP_PACKAGE + ".GenericObject").isAssignableFrom(fieldType) && !getClassFromName(SIP_PACKAGE + ".GenericObjectList").isAssignableFrom(fieldType)) { continue; } else if ((f.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE) { continue; } try { if (fieldType.equals(replacementClass)) { if (GenericObject.isMySubclass(replacementClass)) { GenericObject obj = (GenericObject) f.get(this); if (!matchSubstring) { if (objectText.compareTo(obj.encode()) == 0) { f.set(this, replacement); } } else { if (obj.encode().indexOf(objectText) >= 0) { f.set(this, replacement); } } } else if (GenericObjectList.isMySubclass(replacementClass)) { GenericObjectList obj = (GenericObjectList) f.get(this); if (!matchSubstring) { if (objectText.compareTo(obj.encode()) == 0) { f.set(this, replacement); } } else { if (obj.encode().indexOf(objectText) >= 0) { f.set(this, replacement); } } } } else if (getClassFromName(SIP_PACKAGE + ".GenericObject").isAssignableFrom(fieldType)) { GenericObject g = (GenericObject) f.get(this); g.replace(objectText, replacement, matchSubstring); } else if (getClassFromName(SIP_PACKAGE + ".GenericObjectList") .isAssignableFrom(fieldType)) { GenericObjectList g = (GenericObjectList) f.get(this); g.replace(objectText, replacement, matchSubstring); } } catch (IllegalAccessException ex) { InternalErrorHandler.handleException(ex); } } }
/** * An introspection based predicate matching using a template object. Allows for partial match of * two protocl Objects. * * @other the match pattern to test against. The match object has to be of the same type (class). * Primitive types and non-sip fields that are non null are matched for equality. Null in any * field matches anything. Some book-keeping fields are ignored when making the comparison. */ public boolean match(Object other) { if (other == null) return true; if (!this.getClass().equals(other.getClass())) return false; GenericObject that = (GenericObject) other; Class myclass = this.getClass(); Field[] fields = myclass.getDeclaredFields(); Class hisclass = other.getClass(); Field[] hisfields = hisclass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; Field g = hisfields[i]; // Only print protected and public members. int modifier = f.getModifiers(); if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) continue; Class fieldType = f.getType(); String fieldName = f.getName(); if (fieldName.compareTo("stringRepresentation") == 0) { continue; } if (fieldName.compareTo("indentation") == 0) { continue; } if (fieldName.compareTo("inputText") == 0) { continue; } try { // Primitive fields are printed with type: value if (fieldType.isPrimitive()) { String fname = fieldType.toString(); if (fname.compareTo("int") == 0) { if (f.getInt(this) != g.getInt(that)) return false; } else if (fname.compareTo("short") == 0) { if (f.getShort(this) != g.getShort(that)) return false; } else if (fname.compareTo("char") == 0) { if (f.getChar(this) != g.getChar(that)) return false; } else if (fname.compareTo("long") == 0) { if (f.getLong(this) != g.getLong(that)) return false; } else if (fname.compareTo("boolean") == 0) { if (f.getBoolean(this) != g.getBoolean(that)) return false; } else if (fname.compareTo("double") == 0) { if (f.getDouble(this) != g.getDouble(that)) return false; } else if (fname.compareTo("float") == 0) { if (f.getFloat(this) != g.getFloat(that)) return false; } } else { Object myObj = f.get(this); Object hisObj = g.get(that); if (hisObj == myObj) return true; else if (hisObj != null && myObj == null) return false; else if (GenericObject.isMySubclass(myObj.getClass()) && !((GenericObject) myObj).match(hisObj)) return false; else if (hisObj instanceof java.lang.String && myObj instanceof java.lang.String) { if (((String) myObj).compareToIgnoreCase((String) hisObj) != 0) return false; } else if (GenericObjectList.isMySubclass(myObj.getClass()) && !((GenericObjectList) myObj).match(hisObj)) return false; } } catch (IllegalAccessException ex1) { InternalErrorHandler.handleException(ex1); } } return true; }