@Override public boolean replaceChild(Element child, Element by) { if (child == getTarget()) { setTarget((Expression) by); return true; } if (child == getFunction()) { setFunction((Expression) by); return true; } // return replaceChild(arguments, Expression.class, this, child, by); int i = indexOf(child, arguments); if (i >= 0) { Expression old; if (by == null) old = arguments.remove(i).getValue(); else old = arguments.get(i).setValue((Expression) by); if (old != by) { if (old != null) old.setParentElement(null); if (by != null) by.setParentElement(this); } return true; } return super.replaceChild(child, by); }
@SuppressWarnings("unchecked") public boolean insertChild(Element existingChild, Element childToInsert, boolean before) { if (elementListGettersAndSetters == null) { elementListGettersAndSetters = new ArrayList<GetterAndSetterInfo>(); GettersAndSettersHelper gettersAndSetters = getGettersAndSetters(); for (Map.Entry<String, GetterAndSetterInfo> e : gettersAndSetters.gettersAndSetters.entrySet()) { GetterAndSetterInfo p = e.getValue(); if (!p.isFull()) continue; Type returnType = p.getter.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType paramReturnType = (ParameterizedType) returnType; Type rawType = paramReturnType.getRawType(); Type[] typeArguments = paramReturnType.getActualTypeArguments(); Type typeArgument = typeArguments.length == 1 ? typeArguments[0] : null; if (typeArgument != null && typeArgument instanceof Class && rawType instanceof Class) { Class<?> typeClass = (Class<?>) typeArgument; Class<?> rawClass = (Class<?>) rawType; if (Element.class.isAssignableFrom(typeClass) && List.class.isAssignableFrom(rawClass)) { p.elementType = (Class<Element>) typeClass; elementListGettersAndSetters.add( p); // new ListGetterAndSetterInfo(e.getKey(), (Class<Element>)typeClass, // p.getter, p.setter)); } } } } } Class<?> t = existingChild.getClass(), t2 = childToInsert.getClass(); for (GetterAndSetterInfo info : elementListGettersAndSetters) { if (!info.elementType.isAssignableFrom(t) || !info.elementType.isAssignableFrom(t2)) continue; try { List<Element> list = (List<Element>) info.getter.invoke(this); if (list instanceof SemiUnmodifiableList) list = ((SemiUnmodifiableList<Element>) list).getList(); int i = indexOfInstance(existingChild, list); if (i < 0) continue; list.add(before ? i : i + 1, childToInsert); childToInsert.setParentElement(this); return true; } catch (Exception e) { throw new RuntimeException("Implementation bug in " + Element.class + ".insertChild !", e); } } return false; }
@SuppressWarnings("unchecked") public static <T extends Element> boolean replaceChild( List<T> list, Class<T> type, Element parent, Element child, Element by) { int i = indexOfInstance(child, list); if (i >= 0) { T old; if (by == null) old = list.remove(i); else old = list.set(i, type == null ? (T) by : type.cast(by)); if (old != by) { if (old != null) old.setParentElement(null); if (by != null) by.setParentElement(parent); } return true; } return false; }