private void addToPath(Configurable parent, SequenceEncoder.Decoder st, List<Configurable> path) throws PathFormatException { if (st.hasMoreTokens()) { String id = st.nextToken(); String name = null; SequenceEncoder.Decoder st2 = new SequenceEncoder.Decoder(id, ':'); String className = st2.nextToken(); if (st2.hasMoreTokens()) { name = st2.nextToken(); } Configurable[] children = parent.getConfigureComponents(); Configurable match = null; ArrayList<Configurable> partialMatches = new ArrayList<Configurable>(); int i = -1; while (++i < children.length) { if (className.equals(children[i].getClass().getName())) { partialMatches.add(children[i]); if (name == null ? children[i].getConfigureName() == null : name.equals(children[i].getConfigureName())) { match = children[i]; break; } } } if (match != null) { path.add(match); addToPath(match, st, path); } else if (!partialMatches.isEmpty()) { if (!st.hasMoreTokens()) { path.add(partialMatches.get(0)); } else { ArrayList<Configurable> subPath = null; for (Configurable candidate : partialMatches) { ArrayList<Configurable> l = new ArrayList<Configurable>(); try { addToPath(candidate, st.copy(), l); subPath = l; // FIXME: adding to front of an ArrayList! Should we use LinkedList instead? subPath.add(0, candidate); break; } catch (PathFormatException e) { // No match found here. Continue } } if (subPath != null) { path.addAll(subPath); } else { findFailed(className, name, parent); } } } else { findFailed(className, name, parent); } } }
private void findFailed(String className, String name, Configurable parent) throws PathFormatException { String msgName = name; if (msgName == null) { msgName = className.substring(className.lastIndexOf('.') + 1); } throw new PathFormatException( "Could not find " + msgName + " in " + VASSAL.configure.ConfigureTree.getConfigureName(parent.getClass())); }