package wb.android.flex; import android.content.Context; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AutoCompleteTextView; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Spinner; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; class FlexViews { private static final String TAG = "FlexViews"; private static final boolean D = Flex.D; private final Stack<String> ids; private final Stack<FlexViews.Element> elements; private final Stack<List<FlexView>> views; private final HashMap<String, FlexView> viewMap; private final HashMap<String, List<FlexView>> viewGroupChildern; private final FlexViews.Element[] elementCache; enum Element { EDIT_TEXT ("EditText", EditText.class), CHECKBOX ("CheckBox", CheckBox.class), SPINNER ("Spinner", Spinner.class), AUTOCOMPLETE_TEXT_VIEW ("AutoCompleteTextView", AutoCompleteTextView.class), LINEAR_LAYOUT ("LinearLayout", LinearLayout.class); private final String name; private final Class<? extends View> viewClass; private final boolean isViewGroup; private Element(String name, Class<? extends View> c) {this.name = name; this.viewClass = c; this.isViewGroup = (ViewGroup.class.isAssignableFrom(viewClass));} boolean isElement(String localName) {return this.name.equalsIgnoreCase(localName); } boolean isViewGroup() { return isViewGroup; } String elementName() { return name; } Class<? extends View> getViewClass() { return viewClass; } } enum Attribute { CHECKED ("android:checked"), HINT ("android:hint"), ID ("android:id"), LAYOUT_HEIGHT ("android:layout_height"), LAYOUT_WEIGHT ("android:layout_weight"), LAYOUT_WIDTH ("android:layout_width"), TAG ("android:tag"), VISIBILITY ("android:visibility"), TEXT ("android:text"); private String name; private Attribute(String name) {this.name = name;} boolean isTag(String localName) {return this.name.equalsIgnoreCase(localName); } String tagName() { return this.name; } } FlexViews() { this.ids = new Stack<String>(); this.elements = new Stack<FlexViews.Element>(); this.views = new Stack<List<FlexView>>(); this.viewMap = new HashMap<String, FlexView>(); this.viewGroupChildern = new HashMap<String, List<FlexView>>(); this.elementCache = FlexViews.Element.values(); } void startElement(Attributes attributes, String localName) throws SAXException { FlexViews.Element element = null; for (int i=0; i<elementCache.length; i++) { if (elementCache[i].isElement(localName)) { element = elementCache[i]; break; } } if (element == null) throw new SAXException("Undefined FlexViews Element: " + localName); elements.push(element); String id = attributes.getValue(FlexViews.Attribute.ID.tagName()); if (element.isViewGroup()) { if (id == null) throw new SAXException("All ViewGroups require that a \"" + FlexViews.Attribute.ID.tagName() + "\" attribute is defined."); ids.push(id); views.push(new ArrayList<FlexView>()); } else { if (!views.isEmpty()) views.peek().add(new FlexView(attributes, element)); } if (id != null) { if (!viewMap.containsKey(id)) viewMap.put(id, new FlexView(attributes, element)); else throw new SAXException("Views cannot have the same ID: " + id); } } void endElement(String localName) throws SAXException { FlexViews.Element element = null; for (int i=0; i<elementCache.length; i++) { if (elementCache[i].isElement(localName)) { element = elementCache[i]; break; } } if (element == null) throw new SAXException("Undefined FlexViews Element: " + localName); if (elements.pop() != element) throw new SAXException("The end XML tag for " + localName + " did not match the expected tag: " + element.elementName()); if (element.isViewGroup()) viewGroupChildern.put(ids.pop(), views.pop()); } boolean updateView(View view, String id) throws FlexFailedException { if (id == null) return false; if (viewMap.containsKey(id)) { if (D) Log.d(TAG, "Updating View - ID: " + id); viewMap.get(id).update(view); return true; } return false; } boolean updateView(EditText editText, String id) throws FlexFailedException { if (id == null) return false; if (viewMap.containsKey(id)) { if (D) Log.d(TAG, "Updating EditText - ID: " + id); viewMap.get(id).update(editText); return true; } return false; } boolean updateView(CheckBox checkBox, String id) throws FlexFailedException { if (id == null) return false; if (viewMap.containsKey(id)) { if (D) Log.d(TAG, "Updating CheckBox - ID: " + id); viewMap.get(id).update(checkBox); return true; } return false; } boolean addFlexViewsToParent(Context context, ViewGroup parent, String parentID) throws FlexFailedException { if (parentID == null) return false; if (viewGroupChildern.containsKey(parentID)) { List<FlexView> views = viewGroupChildern.get(parentID); final int size = views.size(); for(int i=0; i<size; i++) { views.get(i).buildAndAddToParent(context, parent); } return true; } else { return false; } } }