package ecologylab.serialization.deserializers.pushhandlers; //import java.io.File; //import java.io.IOException; //import java.util.ArrayList; //import java.util.Collection; //import java.util.Map; // //import org.json.simple.parser.ContentHandler; //import org.json.simple.parser.JSONParser; //import org.json.simple.parser.ParseException; // //import ecologylab.generic.Debug; //import ecologylab.net.ParsedURL; //import ecologylab.serialization.ClassDescriptor; //import ecologylab.serialization.DeserializationHookStrategy; //import ecologylab.serialization.ElementState; //import ecologylab.serialization.FieldDescriptor; //import ecologylab.serialization.FieldTypes; //import ecologylab.serialization.RootElementException; //import ecologylab.serialization.SIMPLTranslationException; //import ecologylab.serialization.ScalarUnmarshallingContext; //import ecologylab.serialization.TranslationScope; //import ecologylab.serialization.types.element.IMappable; public class ElementStateJSONHandler // extends Debug implements ContentHandler, FieldTypes, ScalarUnmarshallingContext { // final TranslationScope translationScope; // // ElementState root; // // ElementState currentElementState; // // FieldDescriptor currentFD; // // SIMPLTranslationException jsonTranslationException; // // ArrayList<FieldDescriptor> fdStack = new ArrayList<FieldDescriptor>(); // // ParsedURL purlContext; // // File fileContext; // // DeserializationHookStrategy deserializationHookStrategy; // // // int numOfCollectionElements = 0; // // ArrayList<Integer> elementsInCollection = new ArrayList<Integer>(); // // public ElementStateJSONHandler(TranslationScope translationScope) // { // this.translationScope = translationScope; // } // // public ElementState parse(CharSequence charSequence) // { // try // { // // JSONParser parser = new JSONParser(); // parser.parse(charSequence.toString(), this); // return root; // } // catch (Exception ex) // { // ex.printStackTrace(); // } // // return null; // } // // @Override // public boolean endArray() throws ParseException, IOException // { // pop(); // // numOfCollectionElements = 0; // return true; // } // // @Override // public void endJSON() throws ParseException, IOException // { // if ((jsonTranslationException == null) && (root != null)) // root.deserializationPostHook(); // // // ElementState.recycleDeserializationMappings(); // } // // @Override // public boolean endObject() throws ParseException, IOException // { // // return true; // } // // @Override // public boolean endObjectEntry() throws ParseException, IOException // { // if (jsonTranslationException != null) // return false; // // FieldDescriptor currentFD = this.currentFD; // final int curentFdType = currentFD.getType(); // // ElementState currentES = this.currentElementState; // processPendingScalar(curentFdType, currentES); // // final ElementState parentES; // // if (currentES.parents == null || currentES.parents.isEmpty()) // parentES = currentES.parent; // else // parentES = currentES.parents.peek(); // // switch (curentFdType) // // every good push deserves a pop :-) (and othertimes, not!) // { // case MAP_ELEMENT: // if (currentES instanceof IMappable) // { // final Object key = ((IMappable) currentES).key(); // Map map = (Map) currentFD.automaticLazyGetCollectionOrMap(parentES); // // Map map = currentFD.getMap(parentES); // map.put(key, currentES); // } // case COMPOSITE_ELEMENT: // case COLLECTION_ELEMENT: // case NAME_SPACE_NESTED_ELEMENT: // if (parentES != null) // parentES.createChildHook(currentES); // else // debug("cool - post ns element"); // currentES.deserializationPostHook(); // if (deserializationHookStrategy != null) // deserializationHookStrategy.deserializationPostHook(currentES, currentFD); // this.currentElementState = currentES.parent; // case NAME_SPACE_SCALAR: // // case WRAPPER: // this.currentElementState = parentES; // restore context! // break; // default: // break; // } // // end of the Namespace object, so we gotta pop it off, too. // // if (curentN2JOType == NAME_SPACE_NESTED_ELEMENT) // // this.currentElementState = this.currentElementState.parent; // popAndPeekFD(); // // if (currentES.parents != null && !currentES.parents.isEmpty() && currentES.parents.size() > 1) // currentES.parents.pop(); // // // return true; // } // // private void setRoot(ElementState root) // { // this.root = root; // this.currentElementState = root; // } // // private ClassDescriptor currentClassDescriptor() // { // if (currentElementState != null) // return this.currentElementState.classDescriptor(); // else // return null; // } // // private void pushFD(FieldDescriptor fd) // { // this.fdStack.add(fd); // } // // private void popAndPeekFD() // { // ArrayList<FieldDescriptor> stack = this.fdStack; // int last = stack.size() - 1; // if (last >= 0) // { // FieldDescriptor result = stack.remove(last--); // if (last >= 0) // result = stack.get(last); // this.currentFD = result; // // printStack("After Pop"); // } // } // // /** // * Assign pending value to a @simpl_scalar // * // * @param curentN2JOType // * @param currentES // */ // private void processPendingScalar(final int curentN2JOType, ElementState currentES) // { // final int length = currentTextValue.length(); // if (length > 0) // { // try // { // switch (curentN2JOType) // { // case NAME_SPACE_SCALAR: // case SCALAR: // // TODO -- unmarshall to set field with scalar type // // copy from the StringBuilder // String value = stringToDeserializeAsScalar(length); // currentFD.setFieldToScalar(currentES, value, this); // break; // case COLLECTION_SCALAR: // value = stringToDeserializeAsScalar(length); // currentFD.addLeafNodeToCollection(currentES, value, this); // break; // case COMPOSITE_ELEMENT: // case COLLECTION_ELEMENT: // case PSEUDO_FIELD_DESCRIPTOR: // // TODO - is this code used???? // // optimizations in currentN2JO are for its parent (they were in scope when it was // // constructed) // // so we get the optimizations we need from the currentElementState // // FIXME -- implement this!!! // FieldDescriptor scalarTextFD = currentElementState.classDescriptor().getScalarTextFD(); // if (scalarTextFD != null) // { // value = stringToDeserializeAsScalar(length); // scalarTextFD.setFieldToScalar(currentES, value, this); // } // break; // default: // break; // } // } // catch (SIMPLTranslationException e) // { // this.jsonTranslationException = e; // } // // currentTextValue.setLength(0); // } // } // // private FieldDescriptor makeIgnoredFieldDescriptor(String key, // ClassDescriptor currentClassDescriptor) // { // FieldDescriptor activeFieldDescriptor; // currentClassDescriptor.warning(" Ignoring key <" + key + ">"); // activeFieldDescriptor = new FieldDescriptor(key); // TODO -- should we record // // declaringClass in here??! // if (activeFieldDescriptor.getTagName() != null) // currentClassDescriptor.addFieldDescriptorMapping(activeFieldDescriptor); // return activeFieldDescriptor; // } // // /** // * Get the String that will be marshalled into the value with a ScalarType, using the // * currentTextValue state variable from the parse, and the length parameter. If appropriate, use // * the currentFD to perform a regex filter on the value before passing it to the appropriate // * scalar marshalling and field or collection element setter. // * // * @param length // * @return // */ // private String stringToDeserializeAsScalar(final int length) // { // String result = new String(currentTextValue.substring(0, length)); // if (translationScope.isPerformFilters()) // result = currentFD.filterValue(result); // return result; // } // // void printStack(String msg) // { // currentElementState.debug("Stack -- " + msg + "\t[" + this.currentElementState + "]"); // for (FieldDescriptor thatFD : fdStack) // { // println(thatFD.getTagName() + " - 0x" + Integer.toHexString(thatFD.getType())); // } // println(""); // } // // StringBuilder currentTextValue = new StringBuilder(1024); // // @Override // public boolean primitive(Object value) throws ParseException, IOException // { // if (jsonTranslationException != null) // return true; // // if (currentFD != null) // { // int n2joType = currentFD.getType(); // switch (n2joType) // { // case SCALAR: // case COLLECTION_SCALAR: // currentTextValue.append(value.toString()); // processPendingScalar(n2joType, currentElementState); // // TODO -- unmarshall to set field with scalar type // break; // case COMPOSITE_ELEMENT: // case COLLECTION_ELEMENT: // case PSEUDO_FIELD_DESCRIPTOR: // // optimizations in currentN2JO are for its parent (they were in scope when it was // // constructed) // // so we get the optimizations we need from the currentElementState // if (currentElementState.classDescriptor().hasScalarFD()) // currentTextValue.append(value.toString()); // break; // default: // // TODO ?! can we dump characters in this case, or should we append to textNode?! // // currentElementState.appendLeafXML(buffy, leafElementName, leafValue, needsEscaping, // // isCDATA) // break; // } // } // // return true; // } // // @Override // public boolean startArray() throws ParseException, IOException // { // push(0); // return true; // } // // @Override // public void startJSON() throws ParseException, IOException // { // // TODO Auto-generated method stub // // } // // @Override // public boolean startObject() throws ParseException, IOException // { // // hack to deal with json arrays with list tag outside the array. // if (currentFD != null) // if (currentFD.isCollection() && !currentFD.isPolymorphic()) // { // if (top() != 0) // { // if (currentFD.isWrapped()) // { // endObjectEntry(); // startObjectEntry(currentFD.getCollectionOrMapTagName()); // } // else // { // FieldDescriptor lastFD = currentFD; // endObjectEntry(); // startObjectEntry(lastFD.getCollectionOrMapTagName()); // } // } // incrementTop(); // // numOfCollectionElements++; // } // // return true; // } // // @Override // public boolean startObjectEntry(String key) throws ParseException, IOException // { // if (jsonTranslationException != null) // return false; // // FieldDescriptor childFD = null; // final boolean isRoot = (root == null); // if (isRoot) // { // form the root ElementState! // ClassDescriptor rootClassDescriptor = translationScope.getClassDescriptorByTag(key); // if (rootClassDescriptor != null) // { // try // { // ElementState root = null; // if (root == null) // root = rootClassDescriptor.getInstance(); // if (root != null) // { // root.setupRoot(); // setRoot(root); // if (deserializationHookStrategy != null) // deserializationHookStrategy.deserializationPreHook(root, null); // // childFD = rootClassDescriptor.pseudoFieldDescriptor(); // } // else // { // this.jsonTranslationException = new RootElementException(key, translationScope); // return false; // } // } // catch (SIMPLTranslationException e) // { // jsonTranslationException = e; // } // } // else // { // // else, we dont translate this element; we ignore it. // String message = "JSON Translation WARNING: Cant find class object for Root JSON element <" // + key + ">: Ignored. "; // println(message); // jsonTranslationException = new SIMPLTranslationException(message); // return false; // } // } // else // // not root // { // final int currentType = currentFD.getType(); // ElementState currentES = this.currentElementState; // // if there is a pending text node, assign it somehow! // processPendingScalar(currentType, currentES); // // ClassDescriptor currentClassDescriptor = currentClassDescriptor(); // childFD = (currentFD != null) && (currentType == IGNORED_ELEMENT) ? // // new NodeToJavaOptimizations(tagName) : // (nice for debugging; slows us down) // FieldDescriptor.IGNORED_ELEMENT_FIELD_DESCRIPTOR // : (currentType == WRAPPER) ? currentFD.getWrappedFD() : currentClassDescriptor // .getFieldDescriptorByTag(key, translationScope, currentES); // if (childFD == null) // { // childFD = makeIgnoredFieldDescriptor(key, currentClassDescriptor); // } // } // this.currentFD = childFD; // // TODO? -- do we need to avoid this if null from an exception in translating root? // pushFD(childFD); // // printStack("After push"); // // if (isRoot) // return true; // // ElementState currentElementState = this.currentElementState; // ElementState childES = null; // try // { // switch (childFD.getType()) // { // case COMPOSITE_ELEMENT: // childES = childFD.constructChildElementState(currentElementState, key); // // if (childES == null) // { // childFD = makeIgnoredFieldDescriptor(key, currentClassDescriptor()); // } // else // childFD.setFieldToComposite(currentElementState, childES); // // // maybe we // // should do // // this on close // // element // break; // case SCALAR: // // wait for characters to set scalar field // // activeN2JO.setScalarFieldWithLeafNode(activeES, childNode); // break; // case COLLECTION_ELEMENT: // // Collection collection = (Collection) childFD // .automaticLazyGetCollectionOrMap(currentElementState); // if (collection != null) // { // ElementState childElement = childFD.constructChildElementState(currentElementState, key); // childES = childElement; // // if (childES == null) // { // childFD = makeIgnoredFieldDescriptor(key, currentClassDescriptor()); // } // // collection.add(childES); // } // // activeNJO.formElementAndAddToCollection(activeES, childNode); // break; // case COLLECTION_SCALAR: // // wait for characters to create scalar reference type and add to collection // // activeN2JO.addLeafNodeToCollection(activeES, childNode); // break; // case MAP_ELEMENT: // Map map = (Map) childFD.automaticLazyGetCollectionOrMap(currentElementState); // if (map != null) // { // ElementState childElement = childFD.constructChildElementState(currentElementState, key); // // childES = childElement; // if (childES == null) // { // this.currentFD = makeIgnoredFieldDescriptor(key, currentClassDescriptor()); // } // } // // Map map = activeFieldDescriptor.getMap(currentElementState); // // if (map != null) // // { // // childES = activeFieldDescriptor.constructChildElementState(currentElementState, tagName); // // } // break; // case IGNORED_ELEMENT: // // should get a set of Optimizations for this, to represent its subfields // case BAD_FIELD: // case WRAPPER: // default: // break; // // } // if (childES != null) // { // // fill in its attributes // if (deserializationHookStrategy != null) // deserializationHookStrategy.deserializationPreHook(childES, childFD); // // this.currentElementState = childES; // childES.parent = old currentElementState // this.currentFD = childFD; // } // } // catch (SIMPLTranslationException e) // { // this.jsonTranslationException = e; // } // // return true; // } // // /** // * @return the root // */ // public ElementState root() // { // return root; // } // // public File fileContext() // { // return (fileContext != null) ? fileContext : (purlContext != null) ? purlContext.file() : null; // } // // public ParsedURL purlContext() // { // return purlContext; // } // // public Integer pop() // { // int num = 0; // // if (this.elementsInCollection.size() > 0) // { // num = this.elementsInCollection.get(elementsInCollection.size() - 1); // this.elementsInCollection.remove(elementsInCollection.size() - 1); // } // return num; // } // // public void push(Integer num) // { // this.elementsInCollection.add(num); // } // // public int top() // { // int num = 0; // // if (this.elementsInCollection.size() > 0) // { // num = this.elementsInCollection.get(elementsInCollection.size() - 1); // } // return num; // } // // public void incrementTop() // { // int num = pop(); // push(++num); // } }