pax_global_header00006660000000000000000000000064144040577220014517gustar00rootroot0000000000000052 comment=a77ffc4a70e91945603f4947828cd7d4633a3cdb jettison-jettison-1.5.4/000077500000000000000000000000001440405772200152225ustar00rootroot00000000000000jettison-jettison-1.5.4/.github/000077500000000000000000000000001440405772200165625ustar00rootroot00000000000000jettison-jettison-1.5.4/.github/workflows/000077500000000000000000000000001440405772200206175ustar00rootroot00000000000000jettison-jettison-1.5.4/.github/workflows/codeql-analysis.yml000066400000000000000000000053511440405772200244360ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ "master" ] pull_request: # The branches below must be a subset of the branches above branches: [ "master" ] schedule: - cron: '38 10 * * 5' jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'java' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - name: Checkout repository uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v2 # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # If the Autobuild fails above, remove it and uncomment the following three lines. # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. # - run: | # echo "Run, Build Application using script" # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 with: category: "/language:${{matrix.language}}" jettison-jettison-1.5.4/.gitignore000066400000000000000000000002411440405772200172070ustar00rootroot00000000000000.idea/ .mvn/ *.iml *.ipr *.iws .DS_Store .checkstyle .classpath .ekstazi .pmd .pmdruleset .pmdruleset.xml .project .ruleset .settings/ target/ velocity.log bin/ jettison-jettison-1.5.4/LICENSE000066400000000000000000000261361440405772200162370ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jettison-jettison-1.5.4/README.md000066400000000000000000000014001440405772200164740ustar00rootroot00000000000000Jettison is a Java library for converting XML to JSON and vice-versa with the help of StAX (https://en.wikipedia.org/wiki/StAX). It implements XMLStreamWriter and XMLStreamReader and supports Mapped and BadgerFish conventions. Latest release is 1.4.0. For example, with a Mapped convention, JAXB processes JAXB beans and emits XMLStreamWriter events which are processed by Jettison with the XML data being converted to JSON. Likewise, when it reads JSON, it reports XMLStreamReader events for JAXB to populate JAXB beans. Note improving and supporting the Mapped convention code is the main focus of this project. However the pull requests from BadgerFish convention users are welcomed. Jettison was originally created by Dan Diephouse and hosted at Codehause. jettison-jettison-1.5.4/pom.xml000066400000000000000000000172111440405772200165410ustar00rootroot00000000000000 4.0.0 org.codehaus.jettison jettison 1.5.4 bundle Jettison A StAX implementation for JSON. https://github.com/jettison-json/jettison Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0 junit junit 4.13.2 test com.fasterxml.woodstox woodstox-core 6.4.0 test scm:git:http://github.com/jettison-json/jettison.git scm:git:https://github.com/jettison-json/jettison.git https://github.com/jettison-json/jettison jettison-1.5.4 ossrh https://oss.sonatype.org/content/repositories/snapshots ossrh https://oss.sonatype.org/service/local/staging/deploy/maven2/ org.apache.maven.plugins maven-enforcer-plugin 3.0.0 enforce-maven enforce 3.2.5 org.apache.maven.plugins maven-compiler-plugin 3.10.1 1.8 1.8 true true true true org.sonatype.plugins nexus-staging-maven-plugin 1.6.13 true ossrh https://oss.sonatype.org/ true org.apache.felix maven-bundle-plugin true 5.1.6 ${project.artifactId} ${project.groupId}.${project.artifactId} org.codehaus.jettison*;version=${project.version} javax.xml,* ${project.name} ${project.version} <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@))) <_nouses>true org.apache.maven.plugins maven-release-plugin 2.5.3 false clean install deploy -Prelease true release true maven-deploy-plugin 2.8.2 ${deploy.altRepository} true maven-gpg-plugin 3.0.1 sign org.apache.maven.plugins maven-source-plugin attach-sources jar-no-fork org.apache.maven.plugins maven-javadoc-plugin attach-javadocs jar org.apache.maven.plugins maven-project-info-reports-plugin org.apache.maven.plugins maven-javadoc-plugin org.apache.maven.plugins maven-surefire-plugin pertest The Jettison Team https://github.com/jettison-json/jettison jettison-jettison-1.5.4/src/000077500000000000000000000000001440405772200160115ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/000077500000000000000000000000001440405772200167355ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/000077500000000000000000000000001440405772200176565ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/000077500000000000000000000000001440405772200204455ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/000077500000000000000000000000001440405772200222405ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/000077500000000000000000000000001440405772200240775ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractDOMDocumentParser.java000066400000000000000000000064621440405772200317310ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.dom.DOMResult; import org.w3c.dom.Document; /** * An abstract JSON DOM parser * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class AbstractDOMDocumentParser { private AbstractXMLInputFactory inputFactory; protected AbstractDOMDocumentParser(AbstractXMLInputFactory inputFactory) { this.inputFactory = inputFactory; } public Document parse(InputStream input) throws IOException { try { XMLStreamReader streamReader = inputFactory.createXMLStreamReader(input); XMLInputFactory readerFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader = readerFactory.createXMLEventReader(streamReader); // Can not create a STaX writer for a DOMResult in woodstox-3.1.1 /*XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); Document nsDom = getDocumentBuilder().newDocument(); DOMResult result = new DOMResult(nsDom); XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(result);*/ ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(baos); eventWriter.add(eventReader); eventWriter.close(); // This parsing step should not be necessary, if we could output to a DOMResult ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); return getDocumentBuilder().parse(bais); //return nsDom; } catch (Exception ex) { IOException ioex = new IOException("Cannot parse input stream"); ioex.initCause(ex); throw ioex; } } private DocumentBuilder getDocumentBuilder() { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); factory.setValidating(false); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); return builder; } catch (ParserConfigurationException e) { throw new RuntimeException("Failed to create DocumentBuilder", e); } } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractDOMDocumentSerializer.java000066400000000000000000000043331440405772200326010ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.io.IOException; import java.io.OutputStream; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.dom.DOMSource; import org.codehaus.jettison.badgerfish.BadgerFishXMLOutputFactory; import org.w3c.dom.Element; /** * An abstract JSON DOM serializer * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class AbstractDOMDocumentSerializer { private OutputStream output; private AbstractXMLOutputFactory writerFactory; public AbstractDOMDocumentSerializer(OutputStream output, AbstractXMLOutputFactory writerFactory) { this.output = output; this.writerFactory = writerFactory; } public void serialize(Element el) throws IOException { if (output == null) throw new IllegalStateException("OutputStream cannot be null"); try { DOMSource source = new DOMSource(el); XMLInputFactory readerFactory = XMLInputFactory.newInstance(); XMLStreamReader streamReader = readerFactory .createXMLStreamReader(source); XMLEventReader eventReader = readerFactory .createXMLEventReader(streamReader); XMLEventWriter eventWriter = writerFactory .createXMLEventWriter(output); eventWriter.add(eventReader); eventWriter.close(); } catch (XMLStreamException ex) { IOException ioex = new IOException("Cannot serialize: " + el); ioex.initCause(ex); throw ioex; } } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractXMLEventWriter.java000066400000000000000000000104661440405772200312740ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.util.Iterator; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; /** * An XMLEventWriter that delegates to an XMLStreamWriter. * * @author Thomas.Diesler@jboss.com * @since 21-Mar-2008 */ public class AbstractXMLEventWriter implements XMLEventWriter { private XMLStreamWriter streamWriter; public AbstractXMLEventWriter(XMLStreamWriter streamWriter) { this.streamWriter = streamWriter; } public void add(XMLEvent event) throws XMLStreamException { if (event.isStartDocument()) { streamWriter.writeStartDocument(); } else if (event.isStartElement()) { StartElement element = event.asStartElement(); QName elQName = element.getName(); if (elQName.getPrefix().length() > 0 && elQName.getNamespaceURI().length() > 0) streamWriter.writeStartElement(elQName.getPrefix(), elQName .getLocalPart(), elQName.getNamespaceURI()); else if (elQName.getNamespaceURI().length() > 0) streamWriter.writeStartElement(elQName.getNamespaceURI(), elQName.getLocalPart()); else streamWriter.writeStartElement(elQName.getLocalPart()); // Add element namespaces Iterator namespaces = element.getNamespaces(); while (namespaces.hasNext()) { Namespace ns = (Namespace) namespaces.next(); String prefix = ns.getPrefix(); String nsURI = ns.getNamespaceURI(); streamWriter.writeNamespace(prefix, nsURI); } // Add element attributes Iterator attris = element.getAttributes(); while (attris.hasNext()) { Attribute attr = (Attribute) attris.next(); QName atQName = attr.getName(); String value = attr.getValue(); if (atQName.getPrefix().length() > 0 && atQName.getNamespaceURI().length() > 0) streamWriter.writeAttribute(atQName.getPrefix(), atQName .getNamespaceURI(), atQName.getLocalPart(), value); else if (atQName.getNamespaceURI().length() > 0) streamWriter.writeAttribute(atQName.getNamespaceURI(), atQName.getLocalPart(), value); else streamWriter.writeAttribute(atQName.getLocalPart(), value); } } else if (event.isCharacters()) { Characters chars = event.asCharacters(); streamWriter.writeCharacters(chars.getData()); } else if (event.isEndElement()) { streamWriter.writeEndElement(); } else if (event.isEndDocument()) { streamWriter.writeEndDocument(); } else { throw new XMLStreamException("Unsupported event type: " + event); } } public void add(XMLEventReader eventReader) throws XMLStreamException { while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); add(event); } close(); } public void close() throws XMLStreamException { streamWriter.close(); } public void flush() throws XMLStreamException { streamWriter.flush(); } public NamespaceContext getNamespaceContext() { return streamWriter.getNamespaceContext(); } public String getPrefix(String prefix) throws XMLStreamException { return streamWriter.getPrefix(prefix); } public void setDefaultNamespace(String namespace) throws XMLStreamException { streamWriter.setDefaultNamespace(namespace); } public void setNamespaceContext(NamespaceContext nsContext) throws XMLStreamException { streamWriter.setNamespaceContext(nsContext); } public void setPrefix(String prefix, String uri) throws XMLStreamException { streamWriter.setPrefix(prefix, uri); } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractXMLInputFactory.java000066400000000000000000000214111440405772200314350ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.io.*; import javax.xml.stream.EventFilter; import javax.xml.stream.StreamFilter; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLReporter; import javax.xml.stream.XMLResolver; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.util.XMLEventAllocator; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import org.codehaus.jettison.json.JSONTokener; public abstract class AbstractXMLInputFactory extends XMLInputFactory { private final static int INPUT_BUF_SIZE = 1024; private int bufSize = INPUT_BUF_SIZE; protected AbstractXMLInputFactory() { } protected AbstractXMLInputFactory(int bufSize) { this.bufSize = bufSize; } public XMLEventReader createFilteredReader(XMLEventReader arg0, EventFilter arg1) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLStreamReader createFilteredReader(XMLStreamReader arg0, StreamFilter arg1) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(InputStream arg0, String encoding) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(InputStream arg0) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(Reader arg0) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(Source arg0) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(String systemId, InputStream arg1) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(String systemId, Reader arg1) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLEventReader createXMLEventReader(XMLStreamReader arg0) throws XMLStreamException { // TODO Auto-generated method stub return null; } public XMLStreamReader createXMLStreamReader(InputStream is) throws XMLStreamException { return createXMLStreamReader(is, null); } public XMLStreamReader createXMLStreamReader(InputStream is, String charset) throws XMLStreamException { /* !!! This is not really correct: should (try to) auto-detect * encoding, since JSON only allows 3 Unicode-based variants. * For now it's ok to default to UTF-8 though. */ if (charset == null) { charset = "UTF-8"; } try { String doc = readAll(is, charset); return createXMLStreamReader(createNewJSONTokener(doc)); } catch (IOException e) { throw new XMLStreamException(e); } } protected JSONTokener createNewJSONTokener(String doc) { return new JSONTokener(doc); } /** * This helper method tries to read and decode input efficiently * into a result String. */ private String readAll(InputStream in, String encoding) throws IOException { final byte[] buffer = new byte[bufSize]; ByteArrayOutputStream bos = null; while (true) { int count = in.read(buffer); if (count < 0) { // EOF break; } /* Let's create buffer lazily, to be able to create something * that's not too small (many resizes) or too big (slower * to allocate): mostly to speed up handling of tiny docs. */ if (bos == null) { int cap; if (count < 64) { cap = 64; } else if (count == bufSize) { // Let's assume there's more coming, not just this chunk cap = bufSize * 4; } else { cap = count; } bos = new ByteArrayOutputStream(cap); } bos.write(buffer, 0, count); } return (bos == null) ? "" : bos.toString(encoding); } public abstract XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException; public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException { try { return createXMLStreamReader(new JSONTokener(readAll(reader))); } catch (IOException e) { throw new XMLStreamException(e); } } private String readAll(Reader r) throws IOException { // Let's see if it's a small doc, can read it all in a single buffer char[] buf = new char[bufSize]; int len = 0; do { int count = r.read(buf, len, buf.length-len); if (count < 0) { // Got it all return (len == 0) ? "" : new String(buf, 0, len); } len += count; } while (len < buf.length); /* Filled the read buffer, need to coalesce. Let's assume there'll * be a bit more data coming */ CharArrayWriter wrt = new CharArrayWriter(bufSize * 4); wrt.write(buf, 0, len); while ((len = r.read(buf)) != -1) { wrt.write(buf, 0, len); } return wrt.toString(); } public XMLStreamReader createXMLStreamReader(Source src) throws XMLStreamException { // Can only support simplest of sources: if (src instanceof StreamSource) { StreamSource ss = (StreamSource) src; InputStream in = ss.getInputStream(); String systemId = ss.getSystemId(); if (in != null) { if (systemId != null) { return createXMLStreamReader(systemId, in); } return createXMLStreamReader(in); } Reader r = ss.getReader(); if (r != null) { if (systemId != null) { return createXMLStreamReader(systemId, r); } return createXMLStreamReader(r); } throw new UnsupportedOperationException("Only those javax.xml.transform.stream.StreamSource instances supported that have an InputStream or Reader"); } throw new UnsupportedOperationException("Only javax.xml.transform.stream.StreamSource type supported"); } public XMLStreamReader createXMLStreamReader(String systemId, InputStream arg1) throws XMLStreamException { // How (if) should the system id be used? return createXMLStreamReader(arg1, null); } public XMLStreamReader createXMLStreamReader(String systemId, Reader r) throws XMLStreamException { return createXMLStreamReader(r); } public XMLEventAllocator getEventAllocator() { // TODO Auto-generated method stub return null; } public Object getProperty(String arg0) throws IllegalArgumentException { // TODO: should gracefully handle standard properties throw new IllegalArgumentException(); } public XMLReporter getXMLReporter() { return null; } public XMLResolver getXMLResolver() { return null; } public boolean isPropertySupported(String arg0) { return false; } public void setEventAllocator(XMLEventAllocator arg0) { // TODO Auto-generated method stub } public void setProperty(String arg0, Object arg1) throws IllegalArgumentException { // TODO: should gracefully handle standard properties throw new IllegalArgumentException(); } public void setXMLReporter(XMLReporter arg0) { // TODO Auto-generated method stub } public void setXMLResolver(XMLResolver arg0) { // TODO Auto-generated method stub } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractXMLOutputFactory.java000066400000000000000000000071371440405772200316470ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.Result; import javax.xml.transform.stream.StreamResult; public abstract class AbstractXMLOutputFactory extends XMLOutputFactory { public XMLEventWriter createXMLEventWriter(OutputStream out, String charset) throws XMLStreamException { return new AbstractXMLEventWriter(createXMLStreamWriter(out, charset)); } public XMLEventWriter createXMLEventWriter(OutputStream out) throws XMLStreamException { return new AbstractXMLEventWriter(createXMLStreamWriter(out)); } public XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException { return new AbstractXMLEventWriter(createXMLStreamWriter(result)); } public XMLEventWriter createXMLEventWriter(Writer writer) throws XMLStreamException { return new AbstractXMLEventWriter(createXMLStreamWriter(writer)); } public XMLStreamWriter createXMLStreamWriter(OutputStream out, String charset) throws XMLStreamException { if (charset == null) { charset = "UTF-8"; } try { return createXMLStreamWriter(new OutputStreamWriter(out, charset)); } catch (UnsupportedEncodingException e) { throw new XMLStreamException(e); } } public XMLStreamWriter createXMLStreamWriter(OutputStream out) throws XMLStreamException { return createXMLStreamWriter(out, null); } public XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException { // Can only support simplest of Result impls: if (result instanceof StreamResult) { StreamResult sr = (StreamResult) result; OutputStream out = sr.getOutputStream(); if (out != null) { return createXMLStreamWriter(out); } Writer w = sr.getWriter(); if (w != null) { return createXMLStreamWriter(w); } throw new UnsupportedOperationException("Only those javax.xml.transform.stream.StreamResult instances supported that have an OutputStream or Writer"); } throw new UnsupportedOperationException("Only javax.xml.transform.stream.StreamResult type supported"); } public abstract XMLStreamWriter createXMLStreamWriter(Writer writer) throws XMLStreamException; public Object getProperty(String arg0) throws IllegalArgumentException { // TODO Auto-generated method stub return null; } public boolean isPropertySupported(String arg0) { // TODO Auto-generated method stub return false; } public void setProperty(String arg0, Object arg1) throws IllegalArgumentException { // TODO Auto-generated method stub } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractXMLStreamReader.java000066400000000000000000000126431440405772200313730ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.util.Iterator; import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; public abstract class AbstractXMLStreamReader implements XMLStreamReader { protected int event; protected Node node; public boolean isAttributeSpecified(int index) { return false; } public boolean isCharacters() { return event == CHARACTERS; } public boolean isEndElement() { return event == END_ELEMENT; } public boolean isStandalone() { return false; } public boolean isStartElement() { return event == START_ELEMENT; } public boolean isWhiteSpace() { return false; } public int nextTag() throws XMLStreamException { int event = next(); while (event != START_ELEMENT && event != END_ELEMENT) { event = next(); } return event; } public int getEventType() { return event; } public void require(int arg0, String arg1, String arg2) throws XMLStreamException { } public int getAttributeCount() { return node.getAttributes().size(); } public String getAttributeLocalName(int n) { return getAttributeName(n).getLocalPart(); } public QName getAttributeName(int n) { Iterator itr = node.getAttributes().keySet().iterator(); QName name = null; for (int i = 0; i <= n; i++) { name = (QName) itr.next(); } return name; } public String getAttributeNamespace(int n) { return getAttributeName(n).getNamespaceURI(); } public String getAttributePrefix(int n) { return getAttributeName(n).getPrefix(); } public String getAttributeValue(int n) { Iterator itr = node.getAttributes().values().iterator(); String name = null; for (int i = 0; i <= n; i++) { name = (String) itr.next(); } return name; } public String getAttributeValue(String ns, String local) { return (String) node.getAttributes().get(new QName(ns, local)); } public String getAttributeType(int index) { return "CDATA"; } public String getLocalName() { return getName().getLocalPart(); } public QName getName() { return node.getName(); } public String getNamespaceURI() { return getName().getNamespaceURI(); } public int getNamespaceCount() { return node.getNamespaceCount(); } public String getNamespacePrefix(int n) { return node.getNamespacePrefix(n); } public String getNamespaceURI(int n) { return node.getNamespaceURI(n); } public String getNamespaceURI(String prefix) { return node.getNamespaceURI(prefix); } public boolean hasName() { // TODO Auto-generated method stub return false; } public boolean hasNext() throws XMLStreamException { return event != END_DOCUMENT; } public boolean hasText() { return event == CHARACTERS; } public boolean standaloneSet() { return false; } public String getCharacterEncodingScheme() { return null; } public String getEncoding() { return null; } public Location getLocation() { return new Location() { public int getCharacterOffset() { return 0; } public int getColumnNumber() { return 0; } public int getLineNumber() { return -1; } public String getPublicId() { return null; } public String getSystemId() { return null; } }; } public String getPIData() { return null; } public String getPITarget() { return null; } public String getPrefix() { return getName().getPrefix(); } public Object getProperty(String arg0) throws IllegalArgumentException { return null; } public String getVersion() { return null; } public char[] getTextCharacters() { String text = getText(); return text != null ? text.toCharArray() : new char[]{}; } public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { String text = getText(); if (text != null) { text.getChars(sourceStart,sourceStart+length,target,targetStart); return length; } else { return 0; } } public int getTextLength() { String text = getText(); return text != null ? text.length() : 0; } public int getTextStart() { return 0; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/AbstractXMLStreamWriter.java000066400000000000000000000057711440405772200314510ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.util.ArrayList; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; public abstract class AbstractXMLStreamWriter implements XMLStreamWriter { private ArrayList serializedAsArrays = new ArrayList(); private boolean arrayKeysWithSlashAvailable; public void writeCData(String text) throws XMLStreamException { writeCharacters(text); } public void writeCharacters(char[] arg0, int arg1, int arg2) throws XMLStreamException { writeCharacters(new String(arg0, arg1, arg2)); } public void writeEmptyElement(String prefix, String local, String ns) throws XMLStreamException { writeStartElement(prefix, local, ns); writeEndElement(); } public void writeEmptyElement(String ns, String local) throws XMLStreamException { writeStartElement(local, ns); writeEndElement(); } public void writeEmptyElement(String local) throws XMLStreamException { writeStartElement(local); writeEndElement(); } public void writeStartDocument(String arg0, String arg1) throws XMLStreamException { writeStartDocument(); } public void writeStartDocument(String arg0) throws XMLStreamException { writeStartDocument(); } public void writeStartElement(String ns, String local) throws XMLStreamException { writeStartElement("", local, ns); } public void writeStartElement(String local) throws XMLStreamException { writeStartElement("", local, ""); } public void writeComment(String arg0) throws XMLStreamException { } public void writeDTD(String arg0) throws XMLStreamException { } public void writeEndDocument() throws XMLStreamException { } public void serializeAsArray(String name) { serializedAsArrays.add(name); if (!arrayKeysWithSlashAvailable) { arrayKeysWithSlashAvailable = name.contains("/"); } } /** * @deprecated since 1.2 because of misspelling. Use serializeAsArray(String name) instead. * @param name the name */ @Deprecated public void seriliazeAsArray(String name) { serializedAsArrays.add(name); } public ArrayList getSerializedAsArrays() { return serializedAsArrays; } public boolean isArrayKeysWithSlashAvailable() { return arrayKeysWithSlashAvailable; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/Convention.java000066400000000000000000000020161440405772200270630ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public interface Convention { void processAttributesAndNamespaces(Node n, JSONObject object) throws JSONException, XMLStreamException; QName createQName(String name, Node node) throws XMLStreamException; } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/JSONSequenceTooLargeException.java000066400000000000000000000015361440405772200325250ustar00rootroot00000000000000/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import org.codehaus.jettison.json.JSONException; public class JSONSequenceTooLargeException extends JSONException { private static final long serialVersionUID = -8281225263069171596L; public JSONSequenceTooLargeException(String message) { super(message); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/Node.java000066400000000000000000000120721440405772200256310ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public class Node { JSONObject object; Map attributes; Map namespaces; Iterator keys; QName name; JSONArray array; int arrayIndex; String currentKey; Node parent; public Node(Node parent, String name, JSONObject object, Convention con) throws JSONException, XMLStreamException { this.parent = parent; this.object = object; /* Should really use a _Linked_ HashMap to preserve * ordering (insert order) -- regular one has arbitrary ordering. * But there are some funky dependencies within unit tests * that will fail right now, need to investigate that bit more */ this.namespaces = new LinkedHashMap(); this.attributes = new LinkedHashMap(); con.processAttributesAndNamespaces(this, object); keys = object.keys(); this.name = con.createQName(name, this); } public Node(String name, Convention con) throws XMLStreamException { this.name = con.createQName(name, this); this.namespaces = new HashMap(); this.attributes = new HashMap(); } public Node(JSONObject object) { this.object = object; this.namespaces = new HashMap(); this.attributes = new HashMap(); } public int getNamespaceCount() { return namespaces.size(); } public String getNamespaceURI(String prefix) { String result = (String) namespaces.get(prefix); if (result == null && parent != null) { result = parent.getNamespaceURI(prefix); } return result; } public String getNamespaceURI(int index) { if (index < 0 || index >= getNamespaceCount()) { throw new IllegalArgumentException("Illegal index: element has "+getNamespaceCount()+" namespace declarations"); } Iterator itr = namespaces.values().iterator(); while (--index >= 0) { itr.next(); } Object ns = itr.next(); return ns == null ? "" : ns.toString(); } public String getNamespacePrefix(String URI) { String result = null; for (Iterator nsItr = namespaces.entrySet().iterator(); nsItr.hasNext();) { Map.Entry e = (Map.Entry) nsItr.next(); if (e.getValue().equals(URI)) { result = (String) e.getKey(); } } if (result == null && parent != null) { result = parent.getNamespacePrefix(URI); } return result; } public String getNamespacePrefix(int index) { if (index < 0 || index >= getNamespaceCount()) { throw new IllegalArgumentException("Illegal index: element has "+getNamespaceCount()+" namespace declarations"); } Iterator itr = namespaces.keySet().iterator(); while (--index >= 0) { itr.next(); } return itr.next().toString(); } public void setNamespaces(Map namespaces) { this.namespaces = namespaces; } public void setNamespace(String prefix, String uri) { namespaces.put(prefix, uri); } public Map getAttributes() { return attributes; } public void setAttribute(QName name, String value) { attributes.put(name, value); } public Iterator getKeys() { return keys; } public QName getName() { return name; } public JSONObject getObject() { return object; } public void setObject(JSONObject object) { this.object = object; } public JSONArray getArray() { return array; } public void setArray(JSONArray array) { this.array = array; } public int getArrayIndex() { return arrayIndex; } public void setArrayIndex(int arrayIndex) { this.arrayIndex = arrayIndex; } public String getCurrentKey() { return currentKey; } public void setCurrentKey(String currentKey) { this.currentKey = currentKey; } public String toString() { if (this.name != null) { return this.name.toString(); } else { return super.toString(); } } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/XsonNamespaceContext.java000066400000000000000000000033231440405772200310540ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison; import java.util.Iterator; import java.util.Map; import javax.xml.namespace.NamespaceContext; import org.codehaus.jettison.util.FastStack; public class XsonNamespaceContext implements NamespaceContext { private FastStack nodes; public XsonNamespaceContext(FastStack nodes) { super(); this.nodes = nodes; } public String getNamespaceURI(String prefix) { for (Iterator itr = nodes.iterator(); itr.hasNext();){ Node node = (Node) itr.next(); String uri = node.getNamespaceURI(prefix); if (uri != null) { return uri; } } return null; } public String getPrefix(String namespaceURI) { for (Iterator itr = nodes.iterator(); itr.hasNext();){ Node node = (Node) itr.next(); String prefix = node.getNamespacePrefix(namespaceURI); if (prefix != null) { return prefix; } } return null; } public Iterator getPrefixes(String namespaceURI) { return null; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/000077500000000000000000000000001440405772200261755ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/BadgerFishConvention.java000066400000000000000000000071201440405772200331010ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.util.Iterator; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.Convention; import org.codehaus.jettison.Node; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public class BadgerFishConvention implements Convention { public BadgerFishConvention() { super(); } public void processAttributesAndNamespaces(Node n, JSONObject object) throws JSONException, XMLStreamException { // Read in the attributes, and stop when there are no more for (Iterator itr = object.keys(); itr.hasNext();) { String k = (String) itr.next(); if (k.startsWith("@")) { Object o = object.opt(k); k = k.substring(1); if (k.equals("xmlns")) { // if its a string its a default namespace if (o instanceof JSONObject) { JSONObject jo = (JSONObject) o; for (Iterator pitr = jo.keys(); pitr.hasNext(); ) { String prefix = (String) pitr.next(); String uri = jo.getString(prefix); if (prefix.equals("$")) { prefix = ""; } n.setNamespace(prefix, uri); } } } else { String strValue = (String) o; QName name = null; // note that a non-prefixed attribute name implies NO namespace, // i.e. as opposed to the in-scope default namespace if (k.contains(":")) { name = createQName(k, n); } else { name = new QName(XMLConstants.DEFAULT_NS_PREFIX, k); } n.setAttribute(name, strValue); } itr.remove(); } } } public QName createQName(String rootName, Node node) throws XMLStreamException { int idx = rootName.indexOf(':'); if (idx != -1) { String prefix = rootName.substring(0, idx); String local = rootName.substring(idx+1); String uri = (String) node.getNamespaceURI(prefix); if (uri == null) { throw new XMLStreamException("Invalid prefix " + prefix + " on element " + rootName); } return new QName(uri, local, prefix); } String uri = (String) node.getNamespaceURI(""); if (uri != null) { return new QName(uri, rootName); } return new QName(rootName); } } BadgerFishDOMDocumentParser.java000066400000000000000000000020161440405772200341720ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import org.codehaus.jettison.AbstractDOMDocumentParser; /** * JSON BadgerFish DOM parser * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class BadgerFishDOMDocumentParser extends AbstractDOMDocumentParser { public BadgerFishDOMDocumentParser() { super(new BadgerFishXMLInputFactory()); } } BadgerFishDOMDocumentSerializer.java000066400000000000000000000021351440405772200350510ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.io.OutputStream; import org.codehaus.jettison.AbstractDOMDocumentSerializer; /** * JSON BadgeFish DOM serializer * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class BadgerFishDOMDocumentSerializer extends AbstractDOMDocumentSerializer { public BadgerFishDOMDocumentSerializer(OutputStream output) { super(output, new BadgerFishXMLOutputFactory()); } } BadgerFishXMLInputFactory.java000066400000000000000000000025431440405772200337140ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.codehaus.jettison.AbstractXMLInputFactory; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONTokener; public class BadgerFishXMLInputFactory extends AbstractXMLInputFactory { public BadgerFishXMLInputFactory() { } public XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException { try { JSONObject root = new JSONObject(tokener); return new BadgerFishXMLStreamReader(root); } catch (JSONException e) { throw new XMLStreamException(e); } } } BadgerFishXMLOutputFactory.java000066400000000000000000000021061440405772200341100ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.io.Writer; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.codehaus.jettison.AbstractXMLOutputFactory; public class BadgerFishXMLOutputFactory extends AbstractXMLOutputFactory { public BadgerFishXMLOutputFactory() { } public XMLStreamWriter createXMLStreamWriter(Writer writer) throws XMLStreamException { return new BadgerFishXMLStreamWriter(writer); } } BadgerFishXMLStreamReader.java000066400000000000000000000117341440405772200336450ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.AbstractXMLStreamReader; import org.codehaus.jettison.Node; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.util.FastStack; public class BadgerFishXMLStreamReader extends AbstractXMLStreamReader { private static final BadgerFishConvention CONVENTION = new BadgerFishConvention(); private FastStack nodes; private String currentText; public BadgerFishXMLStreamReader(JSONObject obj) throws JSONException, XMLStreamException { String rootName = (String) obj.keys().next(); this.node = new Node(null, rootName, obj.getJSONObject(rootName), CONVENTION); this.nodes = new FastStack(); nodes.push(node); event = START_DOCUMENT; } public int next() throws XMLStreamException { if (event == START_DOCUMENT) { event = START_ELEMENT; } else { if (event == END_ELEMENT && nodes.size() != 0) { node = (Node) nodes.peek(); } if (node.getArray() != null && node.getArray().length() > node.getArrayIndex()) { Node arrayNode = node; int idx = arrayNode.getArrayIndex(); try { Object o = arrayNode.getArray().get(idx); processKey(node.getCurrentKey(), o); } catch (JSONException e) { throw new XMLStreamException(e); } idx++; arrayNode.setArrayIndex(idx); } else if (node.getKeys() != null && node.getKeys().hasNext()) { processElement(); } else { if (nodes.size() != 0) { event = END_ELEMENT; node = (Node)nodes.pop(); } else { event = END_DOCUMENT; } } } return event; } private void processElement() throws XMLStreamException { try { String nextKey = (String) node.getKeys().next(); Object newObj = node.getObject().get(nextKey); processKey(nextKey, newObj); } catch (JSONException e) { throw new XMLStreamException(e); } } private void processKey(String nextKey, Object newObj) throws JSONException, XMLStreamException { if (nextKey.equals("$")) { event = CHARACTERS; if (newObj instanceof JSONArray) { JSONArray arr = (JSONArray)newObj; StringBuilder buf = new StringBuilder(); for (int i = 0; i < arr.length(); i++) { buf.append(arr.get(i)); } currentText = buf.toString(); } else { currentText = newObj == null ? null : newObj.toString(); } return; } else if (newObj instanceof JSONObject) { node = new Node((Node)nodes.peek(), nextKey, (JSONObject) newObj, CONVENTION); nodes.push(node); event = START_ELEMENT; return; } else if (newObj instanceof JSONArray) { JSONArray arr = (JSONArray) newObj; if (arr.length() == 0) { next(); return; } // save some state information... node.setArray(arr); node.setArrayIndex(1); node.setCurrentKey(nextKey); processKey(nextKey, arr.get(0)); } else { throw new JSONException("Element [" + nextKey + "] did not contain object, array or text content."); } } public void close() throws XMLStreamException { } public String getAttributeType(int arg0) { return null; } public String getCharacterEncodingScheme() { return null; } public String getElementText() throws XMLStreamException { return currentText; } public NamespaceContext getNamespaceContext() { return null; } public String getText() { return currentText; } } BadgerFishXMLStreamWriter.java000066400000000000000000000166451440405772200337250ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.io.IOException; import java.io.Writer; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.AbstractXMLStreamWriter; import org.codehaus.jettison.Node; import org.codehaus.jettison.XsonNamespaceContext; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.util.FastStack; public class BadgerFishXMLStreamWriter extends AbstractXMLStreamWriter { private JSONObject root; private JSONObject currentNode; private Writer writer; private FastStack nodes; private String currentKey; private NamespaceContext ctx; public BadgerFishXMLStreamWriter(Writer writer) { this(writer, new JSONObject()); } public BadgerFishXMLStreamWriter(Writer writer, JSONObject currentNode) { this(writer, new JSONObject(), new FastStack()); } public BadgerFishXMLStreamWriter(Writer writer, JSONObject currentNode, FastStack nodes) { super(); this.currentNode = currentNode; this.root = currentNode; this.writer = writer; this.nodes = nodes; this.ctx = new XsonNamespaceContext(nodes); } public void close() throws XMLStreamException { } public void flush() throws XMLStreamException { } public NamespaceContext getNamespaceContext() { return ctx; } public String getPrefix(String ns) throws XMLStreamException { return getNamespaceContext().getPrefix(ns); } public Object getProperty(String arg0) throws IllegalArgumentException { return null; } public void setDefaultNamespace(String arg0) throws XMLStreamException { } public void setNamespaceContext(NamespaceContext context) throws XMLStreamException { this.ctx = context; } public void setPrefix(String arg0, String arg1) throws XMLStreamException { } public void writeAttribute(String p, String ns, String local, String value) throws XMLStreamException { String key = createAttributeKey(p, ns, local); try { getCurrentNode().put(key, value); } catch (JSONException e) { throw new XMLStreamException(e); } } private String createAttributeKey(String p, String ns, String local) { return "@" + createKey(p, ns, local); } private String createKey(String p, String ns, String local) { if (p == null || p.equals("")) { return local; } return p + ":" + local; } public void writeAttribute(String ns, String local, String value) throws XMLStreamException { writeAttribute(null, ns, local, value); } public void writeAttribute(String local, String value) throws XMLStreamException { writeAttribute(null, local, value); } public void writeCharacters(String text) throws XMLStreamException { text = text.trim(); if (text.length() == 0) { return; } try { Object o = getCurrentNode().opt("$"); if (o instanceof JSONArray) { ((JSONArray) o).put(text); } else if (o instanceof String) { JSONArray arr = new JSONArray(); arr.put(o); arr.put(text); getCurrentNode().put("$", arr); } else { getCurrentNode().put("$", text); } } catch (JSONException e) { throw new XMLStreamException(e); } } public void writeDefaultNamespace(String ns) throws XMLStreamException { writeNamespace("", ns); } public void writeEndElement() throws XMLStreamException { if (getNodes().size() > 1) { getNodes().pop(); currentNode = ((Node) getNodes().peek()).getObject(); } } public void writeEntityRef(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void writeNamespace(String prefix, String ns) throws XMLStreamException { ((Node) getNodes().peek()).setNamespace(prefix, ns); try { JSONObject nsObj = getCurrentNode().optJSONObject("@xmlns"); if (nsObj == null) { nsObj = new JSONObject(); getCurrentNode().put("@xmlns", nsObj); } if (prefix.equals("")) { prefix = "$"; } nsObj.put(prefix, ns); } catch (JSONException e) { throw new XMLStreamException(e); } } public void writeProcessingInstruction(String arg0, String arg1) throws XMLStreamException { // TODO Auto-generated method stub } public void writeProcessingInstruction(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void writeStartDocument() throws XMLStreamException { } public void writeEndDocument() throws XMLStreamException { try { root.write(writer); writer.flush(); } catch (JSONException e) { throw new XMLStreamException(e); } catch (IOException e) { throw new XMLStreamException(e); } } public void writeStartElement(String prefix, String local, String ns) throws XMLStreamException { try { // TODO ns currentKey = createKey(prefix, ns, local); Object existing = getCurrentNode().opt(currentKey); if (existing instanceof JSONObject) { JSONArray array = new JSONArray(); array.put(existing); JSONObject newCurrent = new JSONObject(); array.put(newCurrent); getCurrentNode().put(currentKey, array); currentNode = newCurrent; Node node = new Node(currentNode); getNodes().push(node); } else { JSONObject newCurrent = new JSONObject(); if (existing instanceof JSONArray) { ((JSONArray) existing).put(newCurrent); } else { getCurrentNode().put(currentKey, newCurrent); } currentNode = newCurrent; Node node = new Node(currentNode); getNodes().push(node); } } catch (JSONException e) { throw new XMLStreamException("Could not write start element!", e); } } protected JSONObject getCurrentNode() { return currentNode; } protected FastStack getNodes() { return nodes; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/000077500000000000000000000000001440405772200250505ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONArray.java000066400000000000000000000742561440405772200275010ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; import java.io.IOException; import java.io.Serializable; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.ListIterator; import java.util.Map; /** * A JSONArray is an ordered sequence of values. Its external text form is a * string wrapped in square brackets with commas separating the values. The * internal form is an object having get and opt * methods for accessing the values by index, and put methods for * adding or replacing values. The values can be any of these types: * Boolean, JSONArray, JSONObject, * Number, String, or the * JSONObject.NULL object. *

* The constructor can convert a JSON text into a Java object. The * toString method converts to JSON text. *

* A get method returns a value if one can be found, and throws an * exception if one cannot be found. An opt method returns a * default value instead of throwing an exception, and so is useful for * obtaining optional values. *

* The generic get() and opt() methods return an * object which you can cast or query for type. There are also typed * get and opt methods that do type checking and type * coersion for you. *

* The texts produced by the toString methods strictly conform to * JSON syntax rules. The constructors are more forgiving in the texts they will * accept: *

    *
  • An extra , (comma) may appear just * before the closing bracket.
  • *
  • The null value will be inserted when there * is , (comma) elision.
  • *
  • Strings may be quoted with ' (single * quote).
  • *
  • Strings do not need to be quoted at all if they do not begin with a quote * or single quote, and if they do not contain leading or trailing spaces, * and if they do not contain any of these characters: * { } [ ] / \ : , = ; # and if they do not look like numbers * and if they are not the reserved words true, * false, or null.
  • *
  • Values can be separated by ; (semicolon) as * well as by , (comma).
  • *
  • Numbers may have the 0- (octal) or * 0x- (hex) prefix.
  • *
  • Comments written in the slashshlash, slashstar, and hash conventions * will be ignored.
  • *
* @author JSON.org * @version 2 */ public class JSONArray implements Serializable { /** * The arrayList where the JSONArray's properties are kept. */ private ArrayList myArrayList; /** * When set to true forward slashes are escaped within the array. * When set to false no forward slashes are escaped. * This setting is not inherited to any JSONObject or JSONArray members of the array. * It is only for simple strings. * Escaping needs to be set for each contained JSONObject or JSONArray object. */ private boolean escapeForwardSlashAlways = true; public boolean isEscapeForwardSlashAlways() { return escapeForwardSlashAlways; } public void setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways) { this.escapeForwardSlashAlways = escapeForwardSlashAlways; } /** * Construct an empty JSONArray. */ public JSONArray() { this.myArrayList = new ArrayList(); } /** * Construct an empty JSONArray with a given capacity. * @param capacity the initial capacity */ public JSONArray(int capacity) { this.myArrayList = new ArrayList(capacity); } /** * Construct a JSONArray from a JSONTokener. * @param x A JSONTokener * @throws JSONException If there is a syntax error. */ public JSONArray(JSONTokener x) throws JSONException { this(); if (x.nextClean() != '[') { throw x.syntaxError("A JSONArray text must start with '['"); } char c = x.nextClean(); if (c == 0) { throw x.syntaxError("JSONArray text must end with ']'"); } else if (c == ',') { throw x.syntaxError("JSONArray text has a trailing ','"); } if (c == ']') { return; } x.back(); for (;;) { if (x.nextClean() == ',') { if (c == '[') { throw x.syntaxError("JSONArray text has a trailing ','"); } x.back(); this.myArrayList.add(null); } else { x.back(); this.myArrayList.add(x.nextValue()); } switch (x.nextClean()) { case ';': case ',': char nextClean = x.nextClean(); if (nextClean == 0) { throw x.syntaxError("JSONArray text has a trailing ','"); } else if (nextClean == ']') { return; } x.back(); break; case ']': return; default: throw x.syntaxError("Expected a ',' or ']'"); } } } /** * Construct a JSONArray from a source sJSON text. * @param string A string that begins with * [ (left bracket) * and ends with ] (right bracket). * @throws JSONException If there is a syntax error. */ public JSONArray(String string) throws JSONException { this(new JSONTokener(string)); } /** * Construct a JSONArray from a Collection. * @param collection A Collection. * @throws JSONException If there is a syntax error. */ public JSONArray(Collection collection) throws JSONException { this(collection, 0); } private JSONArray(Collection collection, int recursionDepth) throws JSONException { if (recursionDepth > JSONObject.getGlobalRecursionDepthLimit()) { throw new JSONException("JSONArray has reached recursion depth limit of " + JSONObject.getGlobalRecursionDepthLimit()); } this.myArrayList = (collection == null) ? new ArrayList() : new ArrayList(collection); // ensure a pure hierarchy of JSONObjects and JSONArrays for (ListIterator iter = myArrayList.listIterator(); iter.hasNext();) { Object e = iter.next(); if (e instanceof Collection) { iter.set(new JSONArray((Collection) e, recursionDepth + 1)); } if (e instanceof Map) { iter.set(new JSONObject((Map) e)); } } } /** * Get the object value associated with an index. * @param index * The index must be between 0 and length() - 1. * @return An object value. * @throws JSONException If there is no value for the index. */ public Object get(int index) throws JSONException { Object o = opt(index); if (o == null) { throw new JSONException("JSONArray[" + index + "] not found."); } return o; } /** * Get the boolean value associated with an index. * The string values "true" and "false" are converted to boolean. * * @param index The index must be between 0 and length() - 1. * @return The truth. * @throws JSONException If there is no value for the index or if the * value is not convertable to boolean. */ public boolean getBoolean(int index) throws JSONException { Object o = get(index); if (o.equals(Boolean.FALSE) || (o instanceof String && ((String)o).equalsIgnoreCase("false"))) { return false; } else if (o.equals(Boolean.TRUE) || (o instanceof String && ((String)o).equalsIgnoreCase("true"))) { return true; } throw new JSONException("JSONArray[" + index + "] is not a Boolean."); } /** * Get the double value associated with an index. * * @param index The index must be between 0 and length() - 1. * @return The value. * @throws JSONException If the key is not found or if the value cannot * be converted to a number. */ public double getDouble(int index) throws JSONException { Object o = get(index); try { return o instanceof Number ? ((Number)o).doubleValue() : Double.valueOf((String)o).doubleValue(); } catch (Exception e) { throw new JSONException("JSONArray[" + index + "] is not a number."); } } /** * Get the int value associated with an index. * * @param index The index must be between 0 and length() - 1. * @return The value. * @throws JSONException If the key is not found or if the value cannot * be converted to a number. * if the value cannot be converted to a number. */ public int getInt(int index) throws JSONException { Object o = get(index); return o instanceof Number ? ((Number)o).intValue() : (int)getDouble(index); } /** * Get the JSONArray associated with an index. * @param index The index must be between 0 and length() - 1. * @return A JSONArray value. * @throws JSONException If there is no value for the index. or if the * value is not a JSONArray */ public JSONArray getJSONArray(int index) throws JSONException { Object o = get(index); if (o instanceof JSONArray) { return (JSONArray)o; } throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); } /** * Get the JSONObject associated with an index. * @param index subscript * @return A JSONObject value. * @throws JSONException If there is no value for the index or if the * value is not a JSONObject */ public JSONObject getJSONObject(int index) throws JSONException { Object o = get(index); if (o instanceof JSONObject) { return (JSONObject)o; } throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); } /** * Get the long value associated with an index. * * @param index The index must be between 0 and length() - 1. * @return The value. * @throws JSONException If the key is not found or if the value cannot * be converted to a number. */ public long getLong(int index) throws JSONException { Object o = get(index); return o instanceof Number ? ((Number)o).longValue() : (long)getDouble(index); } /** * Get the string associated with an index. * @param index The index must be between 0 and length() - 1. * @return A string value. * @throws JSONException If there is no value for the index. */ public String getString(int index) throws JSONException { return get(index).toString(); } /** * Determine if the value is null. * @param index The index must be between 0 and length() - 1. * @return true if the value at the index is null, or if there is no value. */ public boolean isNull(int index) { return JSONObject.NULL.equals(opt(index)); } /** * Make a string from the contents of this JSONArray. The * separator string is inserted between each element. * Warning: This method assumes that the data structure is acyclical. * @param separator A string that will be inserted between the elements. * @return a string. * @throws JSONException If the array contains an invalid number. */ public String join(String separator) throws JSONException { int len = length(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < len; i += 1) { if (i > 0) { sb.append(separator); } sb.append(JSONObject.valueToString(this.myArrayList.get(i), escapeForwardSlashAlways)); } return sb.toString(); } /** * Get the number of elements in the JSONArray, included nulls. * * @return The length (or size). */ public int length() { return this.myArrayList.size(); } /** * Get the optional object value associated with an index. * @param index The index must be between 0 and length() - 1. * @return An object value, or null if there is no * object at that index. */ public Object opt(int index) { return (index < 0 || index >= length()) ? null : this.myArrayList.get(index); } /** * Get the optional boolean value associated with an index. * It returns false if there is no value at that index, * or if the value is not Boolean.TRUE or the String "true". * * @param index The index must be between 0 and length() - 1. * @return The truth. */ public boolean optBoolean(int index) { return optBoolean(index, false); } /** * Get the optional boolean value associated with an index. * It returns the defaultValue if there is no value at that index or if * it is not a Boolean or the String "true" or "false" (case insensitive). * * @param index The index must be between 0 and length() - 1. * @param defaultValue A boolean default. * @return The truth. */ public boolean optBoolean(int index, boolean defaultValue) { try { return getBoolean(index); } catch (Exception e) { return defaultValue; } } /** * Get the optional double value associated with an index. * NaN is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * * @param index The index must be between 0 and length() - 1. * @return The value. */ public double optDouble(int index) { return optDouble(index, Double.NaN); } /** * Get the optional double value associated with an index. * The defaultValue is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * * @param index subscript * @param defaultValue The default value. * @return The value. */ public double optDouble(int index, double defaultValue) { try { return getDouble(index); } catch (Exception e) { return defaultValue; } } /** * Get the optional int value associated with an index. * Zero is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * * @param index The index must be between 0 and length() - 1. * @return The value. */ public int optInt(int index) { return optInt(index, 0); } /** * Get the optional int value associated with an index. * The defaultValue is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * @param index The index must be between 0 and length() - 1. * @param defaultValue The default value. * @return The value. */ public int optInt(int index, int defaultValue) { try { return getInt(index); } catch (Exception e) { return defaultValue; } } /** * Get the optional JSONArray associated with an index. * @param index subscript * @return A JSONArray value, or null if the index has no value, * or if the value is not a JSONArray. */ public JSONArray optJSONArray(int index) { Object o = opt(index); return o instanceof JSONArray ? (JSONArray)o : null; } /** * Get the optional JSONObject associated with an index. * Null is returned if the key is not found, or null if the index has * no value, or if the value is not a JSONObject. * * @param index The index must be between 0 and length() - 1. * @return A JSONObject value. */ public JSONObject optJSONObject(int index) { Object o = opt(index); return o instanceof JSONObject ? (JSONObject)o : null; } /** * Get the optional long value associated with an index. * Zero is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * * @param index The index must be between 0 and length() - 1. * @return The value. */ public long optLong(int index) { return optLong(index, 0); } /** * Get the optional long value associated with an index. * The defaultValue is returned if there is no value for the index, * or if the value is not a number and cannot be converted to a number. * @param index The index must be between 0 and length() - 1. * @param defaultValue The default value. * @return The value. */ public long optLong(int index, long defaultValue) { try { return getLong(index); } catch (Exception e) { return defaultValue; } } /** * Get the optional string value associated with an index. It returns an * empty string if there is no value at that index. If the value * is not a string and is not null, then it is coverted to a string. * * @param index The index must be between 0 and length() - 1. * @return A String value. */ public String optString(int index) { return optString(index, ""); } /** * Get the optional string associated with an index. * The defaultValue is returned if the key is not found. * * @param index The index must be between 0 and length() - 1. * @param defaultValue The default value. * @return A String value. */ public String optString(int index, String defaultValue) { Object o = opt(index); return o != null ? o.toString() : defaultValue; } /** * Append a boolean value. This increases the array's length by one. * * @param value A boolean value. * @return this. */ public JSONArray put(boolean value) { put(value ? Boolean.TRUE : Boolean.FALSE); return this; } /** * Put a value in the JSONArray, where the value will be a * JSONArray which is produced from a Collection. * @param value A Collection value. * @return this. * @throws JSONException If there is a syntax error. */ public JSONArray put(Collection value) throws JSONException { put(new JSONArray(value)); return this; } /** * Append a double value. This increases the array's length by one. * * @param value A double value. * @throws JSONException if the value is not finite. * @return this. */ public JSONArray put(double value) throws JSONException { Double d = new Double(value); JSONObject.testValidity(d); put(d); return this; } /** * Append an int value. This increases the array's length by one. * * @param value An int value. * @return this. */ public JSONArray put(int value) { put(Integer.valueOf(value)); return this; } /** * Append an long value. This increases the array's length by one. * * @param value A long value. * @return this. */ public JSONArray put(long value) { put(Long.valueOf(value)); return this; } /** * Put a value in the JSONArray, where the value will be a * JSONObject which is produced from a Map. * @param value A Map value. * @return this. * @throws JSONException If there is a syntax error. */ public JSONArray put(Map value) throws JSONException { put(new JSONObject(value)); return this; } /** * Append an object value. This increases the array's length by one. * @param value An object value. The value should be a * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the * JSONObject.NULL object. * @return this. */ public JSONArray put(Object value) { this.myArrayList.add(value); return this; } public JSONArray remove(Object value) { this.myArrayList.remove(value); return this; } /** * Put or replace a boolean value in the JSONArray. If the index is greater * than the length of the JSONArray, then null elements will be added as * necessary to pad it out. * @param index The subscript. * @param value A boolean value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray put(int index, boolean value) throws JSONException { put(index, value ? Boolean.TRUE : Boolean.FALSE); return this; } /** * Put a value in the JSONArray, where the value will be a * JSONArray which is produced from a Collection. * @param index The subscript. * @param value A Collection value. * @return this. * @throws JSONException If the index is negative or if the value is * not finite. */ public JSONArray put(int index, Collection value) throws JSONException { put(index, new JSONArray(value)); return this; } /** * Put or replace a double value. If the index is greater than the length of * the JSONArray, then null elements will be added as necessary to pad * it out. * @param index The subscript. * @param value A double value. * @return this. * @throws JSONException If the index is negative or if the value is * not finite. */ public JSONArray put(int index, double value) throws JSONException { put(index, new Double(value)); return this; } /** * Put or replace an int value. If the index is greater than the length of * the JSONArray, then null elements will be added as necessary to pad * it out. * @param index The subscript. * @param value An int value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray put(int index, int value) throws JSONException { put(index, Integer.valueOf(value)); return this; } /** * Put or replace a long value. If the index is greater than the length of * the JSONArray, then null elements will be added as necessary to pad * it out. * @param index The subscript. * @param value A long value. * @return this. * @throws JSONException If the index is negative. */ public JSONArray put(int index, long value) throws JSONException { put(index, Long.valueOf(value)); return this; } /** * Put a value in the JSONArray, where the value will be a * JSONObject which is produced from a Map. * @param index The subscript. * @param value The Map value. * @return this. * @throws JSONException If the index is negative or if the the value is * an invalid number. */ public JSONArray put(int index, Map value) throws JSONException { put(index, new JSONObject(value)); return this; } /** * Put or replace an object value in the JSONArray. If the index is greater * than the length of the JSONArray, then null elements will be added as * necessary to pad it out. * @param index The subscript. * @param value The value to put into the array. The value should be a * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the * JSONObject.NULL object. * @return this. * @throws JSONException If the index is negative or if the the value is * an invalid number. */ public JSONArray put(int index, Object value) throws JSONException { JSONObject.testValidity(value); if (index < 0) { throw new JSONException("JSONArray[" + index + "] not found."); } if (index < length()) { this.myArrayList.set(index, value); } else { while (index != length()) { put(JSONObject.NULL); } put(value); } return this; } /** * Produce a JSONObject by combining a JSONArray of names with the values * of this JSONArray. * @param names A JSONArray containing a list of key strings. These will be * paired with the values. * @return A JSONObject, or null if there are no names or if this JSONArray * has no values. * @throws JSONException If any of the names are null. */ public JSONObject toJSONObject(JSONArray names) throws JSONException { if (names == null || names.length() == 0 || length() == 0) { return null; } JSONObject jo = new JSONObject(); for (int i = 0; i < names.length(); i += 1) { jo.put(names.getString(i), this.opt(i)); } return jo; } /** * Make a JSON text of this JSONArray. For compactness, no * unnecessary whitespace is added. If it is not possible to produce a * syntactically correct JSON text then null will be returned instead. This * could occur if the array contains an invalid number. *

* Warning: This method assumes that the data structure is acyclical. * * @return a printable, displayable, transmittable * representation of the array. */ public String toString() { try { return '[' + join(",") + ']'; } catch (Exception e) { return null; } } /** * Make a prettyprinted JSON text of this JSONArray. * Warning: This method assumes that the data structure is acyclical. * @param indentFactor The number of spaces to add to each level of * indentation. * @return a printable, displayable, transmittable * representation of the object, beginning * with [ (left bracket) and ending * with ] (right bracket). * @throws JSONException JSONException */ public String toString(int indentFactor) throws JSONException { return toString(indentFactor, 0); } /** * Make a prettyprinted JSON text of this JSONArray. * Warning: This method assumes that the data structure is acyclical. * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indention of the top level. * @return a printable, displayable, transmittable * representation of the array. * @throws JSONException JSONException */ String toString(int indentFactor, int indent) throws JSONException { int len = length(); if (len == 0) { return "[]"; } int i; StringBuilder sb = new StringBuilder("["); if (len == 1) { sb.append(JSONObject.valueToString(this.myArrayList.get(0), indentFactor, indent, escapeForwardSlashAlways)); } else { int newindent = indent + indentFactor; sb.append('\n'); for (i = 0; i < len; i += 1) { if (i > 0) { sb.append(",\n"); } for (int j = 0; j < newindent; j += 1) { sb.append(' '); } sb.append(JSONObject.valueToString(this.myArrayList.get(i), indentFactor, newindent, escapeForwardSlashAlways)); } sb.append('\n'); for (i = 0; i < indent; i += 1) { sb.append(' '); } } sb.append(']'); return sb.toString(); } @Override public int hashCode() { return myArrayList.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof JSONArray) { return myArrayList.equals(((JSONArray)obj).myArrayList); } else { return false; } } /** * Write the contents of the JSONArray as JSON text to a writer. * For compactness, no whitespace is added. *

* Warning: This method assumes that the data structure is acyclical. * * @param writer The writer. * @return The writer. * @throws JSONException JSONException */ public Writer write(Writer writer) throws JSONException { try { boolean b = false; int len = length(); writer.write('['); for (int i = 0; i < len; i += 1) { if (b) { writer.write(','); } Object v = this.myArrayList.get(i); if (v instanceof JSONObject) { ((JSONObject)v).write(writer); } else if (v instanceof JSONArray) { ((JSONArray)v).write(writer); } else { writer.write(JSONObject.valueToString(v, escapeForwardSlashAlways)); } b = true; } writer.write(']'); return writer; } catch (IOException e) { throw new JSONException(e); } } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONException.java000066400000000000000000000025251440405772200303470ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; /** * The JSONException is thrown by the JSON.org classes then things are amiss. * @author JSON.org * @version 2 */ public class JSONException extends Exception { private int line = -1; private int column = -1; /** * Constructs a JSONException with an explanatory message. * @param message Detail about the reason for the exception. */ public JSONException(String message) { super(message); } public JSONException(String message, int line, int column) { super(message); this.line = line; this.column = column; } public JSONException(Throwable t) { super(t.getMessage(), t); } public int getColumn() { return column; } public int getLine() { return line; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONObject.java000066400000000000000000001360131440405772200276170ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; import java.io.IOException; import java.io.Serializable; import java.io.Writer; import java.lang.reflect.Field; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.codehaus.jettison.JSONSequenceTooLargeException; /** * A JSONObject is an unordered collection of name/value pairs. Its * external form is a string wrapped in curly braces with colons between the * names and values, and commas between the values and names. The internal form * is an object having get and opt methods for * accessing the values by name, and put methods for adding or * replacing values by name. The values can be any of these types: * Boolean, JSONArray, JSONObject, * Number, String, or the JSONObject.NULL * object. A JSONObject constructor can be used to convert an external form * JSON text into an internal form whose values can be retrieved with the * get and opt methods, or to convert values into a * JSON text using the put and toString methods. * A get method returns a value if one can be found, and throws an * exception if one cannot be found. An opt method returns a * default value instead of throwing an exception, and so is useful for * obtaining optional values. *

* The generic get() and opt() methods return an * object, which you can cast or query for type. There are also typed * get and opt methods that do type checking and type * coersion for you. *

* The put methods adds values to an object. For example,

 *     myString = new JSONObject().put("JSON", "Hello, World!").toString();
* produces the string {"JSON": "Hello, World"}. *

* The texts produced by the toString methods strictly conform to * the JSON sysntax rules. * The constructors are more forgiving in the texts they will accept: *

    *
  • An extra , (comma) may appear just * before the closing brace.
  • *
  • Strings may be quoted with ' (single * quote).
  • *
  • Strings do not need to be quoted at all if they do not begin with a quote * or single quote, and if they do not contain leading or trailing spaces, * and if they do not contain any of these characters: * { } [ ] / \ : , = ; # and if they do not look like numbers * and if they are not the reserved words true, * false, or null.
  • *
  • Keys can be followed by = or => as well as * by :.
  • *
  • Values can be followed by ; (semicolon) as * well as by , (comma).
  • *
  • Numbers may have the 0- (octal) or * 0x- (hex) prefix.
  • *
  • Comments written in the slashshlash, slashstar, and hash conventions * will be ignored.
  • *
* @author JSON.org * @version 2 */ public class JSONObject implements Serializable { /** * The default recursion depth limit to prevent stack overflow issues on deeply nested structures. */ final static int DEFAULT_RECURSION_DEPTH_LIMIT = 500; static int RECURSION_DEPTH_LIMIT = DEFAULT_RECURSION_DEPTH_LIMIT; /** * JSONObject.NULL is equivalent to the value that JavaScript calls null, * whilst Java's null is equivalent to the value that JavaScript calls * undefined. */ private static final class Null { boolean explicitNull; public Null() { } public Null(boolean explicitNull) { this.explicitNull = explicitNull; } /** * There is only intended to be a single instance of the NULL object, * so the clone method returns itself. * @return NULL. */ protected final Object clone() { return this; } /** * A Null object is equal to the null value and to itself. * @param object An object to test for nullness. * @return true if the object parameter is the JSONObject.NULL object * or null. */ public boolean equals(Object object) { return object == null || object == this; } /** * Get the "null" string value. * @return The string "null". */ public String toString() { return isExplicitNull() ? null : "null"; } public boolean isExplicitNull() { return explicitNull; } } /** * The hash map where the JSONObject's properties are kept. */ private LinkedHashMap myHashMap; private boolean dropRootElement; private List ignoredElements; private boolean writeNullAsString = true; private boolean escapeForwardSlashAlways = true; /** * It is sometimes more convenient and less ambiguous to have a * NULL object than to use Java's null value. * JSONObject.NULL.equals(null) returns true. * JSONObject.NULL.toString() returns "null". */ public static final Object NULL = new Null(); public static final Object EXPLICIT_NULL = new Null(true); /** * Construct an empty JSONObject. */ public JSONObject() { this(false, null, true, true); } public JSONObject(List ignoredElements) { this(false, ignoredElements, true, true); } public JSONObject(boolean dropRootElement, List ignoredElements, boolean writeNullAsString, boolean escapeForwardSlash) { this.myHashMap = new LinkedHashMap(); this.dropRootElement = dropRootElement; this.ignoredElements = ignoredElements; this.writeNullAsString = writeNullAsString; this.escapeForwardSlashAlways = escapeForwardSlash; } /** * Construct a JSONObject from a subset of another JSONObject. * An array of strings is used to identify the keys that should be copied. * Missing keys are ignored. * @param jo A JSONObject. * @param sa An array of strings. * @exception JSONException If a value is a non-finite number. */ public JSONObject(JSONObject jo, String[] sa) throws JSONException { this(); for (int i = 0; i < sa.length; i += 1) { putOpt(sa[i], jo.opt(sa[i])); } } /** * Construct a JSONObject from a JSONTokener. * @param x A JSONTokener object containing the source string. * @throws JSONException If there is a syntax error in the source string. */ public JSONObject(JSONTokener x) throws JSONException { this(); char c; String key; if (x.nextClean() != '{') { throw x.syntaxError("A JSONObject text must begin with '{'"); } for (;;) { c = x.nextClean(); switch (c) { case 0: throw x.syntaxError("A JSONObject text must end with '}'"); case '}': return; case '{': throw x.syntaxError("Expected a key"); default: x.back(); key = x.nextValue().toString(); } /* * The key is followed by ':'. We will also tolerate '=' or '=>'. */ c = x.nextClean(); if (c == '=') { if (x.next() != '>') { x.back(); } } else if (c != ':') { throw x.syntaxError("Expected a ':' after a key"); } doPut(key, x.nextValue(), x.getThreshold(), true); /* * Pairs are separated by ','. We will also tolerate ';'. */ switch (x.nextClean()) { case ';': case ',': if (x.nextClean() == '}') { return; } x.back(); break; case '}': return; default: throw x.syntaxError("Expected a ',' or '}'"); } } } /** * Construct a JSONObject from a Map. * @param map A map object that can be used to initialize the contents of * the JSONObject. * @throws JSONException If there is a syntax error. */ public JSONObject(Map map) throws JSONException { this(map, 0); } private JSONObject(Map map, int recursionDepth) throws JSONException { if (recursionDepth > RECURSION_DEPTH_LIMIT) { throw new JSONException("JSONObject has reached recursion depth limit of " + RECURSION_DEPTH_LIMIT); } this.myHashMap = (map == null) ? new LinkedHashMap() : new LinkedHashMap(map); // ensure a pure hierarchy of JSONObjects and JSONArrays for (Entry entry : myHashMap.entrySet()) { Object v = entry.getValue(); if (v instanceof Collection) { myHashMap.put(entry.getKey(), new JSONArray((Collection) v)); } if (v instanceof Map && v != map) { myHashMap.put(entry.getKey(), new JSONObject((Map) v, recursionDepth + 1)); } } } /** * Construct a JSONObject from an Object, using reflection to find the * public members. The resulting JSONObject's keys will be the strings * from the names array, and the values will be the field values associated * with those keys in the object. If a key is not found or not visible, * then it will not be copied into the new JSONObject. * @param object An object that has fields that should be used to make a * JSONObject. * @param names An array of strings, the names of the fields to be used * from the object. */ public JSONObject(Object object, String names[]) { this(); Class c = object.getClass(); for (int i = 0; i < names.length; i += 1) { try { String name = names[i]; Field field = c.getField(name); Object value = field.get(object); this.put(name, value); } catch (Exception e) { /* forget about it */ } } } /** * Construct a JSONObject from a string. * This is the most commonly used JSONObject constructor. * @param string A string beginning * with { (left brace) and ending * with } (right brace). * @exception JSONException If there is a syntax error in the source string. */ public JSONObject(String string) throws JSONException { this(new JSONTokener(string)); } /** * Accumulate values under a key. It is similar to the put method except * that if there is already an object stored under the key then a * JSONArray is stored under the key to hold all of the accumulated values. * If there is already a JSONArray, then the new value is appended to it. * In contrast, the put method replaces the previous value. * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the value is an invalid number * or if the key is null. */ public JSONObject accumulate(String key, Object value) throws JSONException { testValidity(value); Object o = opt(key); if (o == null) { put(key, value); } else if (o instanceof JSONArray) { ((JSONArray)o).put(value); } else { put(key, new JSONArray().put(o).put(value)); } return this; } /** * Append values to the array under a key. If the key does not exist in the * JSONObject, then the key is put in the JSONObject with its value being a * JSONArray containing the value parameter. If the key was already * associated with a JSONArray, then the value parameter is appended to it. * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JSONException If the key is null or if the current value * associated with the key is not a JSONArray. */ public JSONObject append(String key, Object value) throws JSONException { testValidity(value); Object o = opt(key); if (o == null) { put(key, new JSONArray().put(value)); } else if (!(o instanceof JSONArray)){ throw new JSONException("JSONObject[" + key + "] is not a JSONArray."); } else { ((JSONArray)o).put(value); } return this; } /** * Produce a string from a double. The string "null" will be returned if * the number is not finite. * @param d A double. * @return A String. */ static public String doubleToString(double d) { if (Double.isInfinite(d) || Double.isNaN(d)) { return "null"; } // Shave off trailing zeros and decimal point, if possible. String s = Double.toString(d); if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { while (s.endsWith("0")) { s = s.substring(0, s.length() - 1); } if (s.endsWith(".")) { s = s.substring(0, s.length() - 1); } } return s; } /** * Get the value object associated with a key. * * @param key A key string. * @return The object associated with the key. * @throws JSONException if the key is not found. */ public Object get(String key) throws JSONException { Object o = opt(key); if (o == null) { throw new JSONException("JSONObject[" + quote(key) + "] not found."); } return o; } /** * Get the boolean value associated with a key. * * @param key A key string. * @return The truth. * @throws JSONException * if the value is not a Boolean or the String "true" or "false". */ public boolean getBoolean(String key) throws JSONException { return doGetBoolean(key, get(key)); } private boolean doGetBoolean(String key, Object o) throws JSONException { if (o.equals(Boolean.FALSE) || (o instanceof String && ((String)o).equalsIgnoreCase("false"))) { return false; } else if (o.equals(Boolean.TRUE) || (o instanceof String && ((String)o).equalsIgnoreCase("true"))) { return true; } throw new JSONException("JSONObject[" + quote(key) + "] is not a Boolean."); } /** * Get the double value associated with a key. * @param key A key string. * @return The numeric value. * @throws JSONException if the key is not found or * if the value is not a Number object and cannot be converted to a number. */ public double getDouble(String key) throws JSONException { return doGetDouble(key, get(key)); } private double doGetDouble(String key, Object o) throws JSONException { try { return o instanceof Number ? ((Number)o).doubleValue() : Double.valueOf((String)o).doubleValue(); } catch (Exception e) { throw new JSONException("JSONObject[" + quote(key) + "] is not a number."); } } /** * Get the int value associated with a key. If the number value is too * large for an int, it will be clipped. * * @param key A key string. * @return The integer value. * @throws JSONException if the key is not found or if the value cannot * be converted to an integer. */ public int getInt(String key) throws JSONException { return doGetInt(key, get(key)); } private int doGetInt(String key, Object o) throws JSONException { return o instanceof Number ? ((Number)o).intValue() : (int)getDouble(key); } /** * Get the JSONArray value associated with a key. * * @param key A key string. * @return A JSONArray which is the value. * @throws JSONException if the key is not found or * if the value is not a JSONArray. */ public JSONArray getJSONArray(String key) throws JSONException { Object o = get(key); if (o instanceof JSONArray) { return (JSONArray)o; } throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray."); } /** * Get the JSONObject value associated with a key. * * @param key A key string. * @return A JSONObject which is the value. * @throws JSONException if the key is not found or * if the value is not a JSONObject. */ public JSONObject getJSONObject(String key) throws JSONException { Object o = get(key); if (o instanceof JSONObject) { return (JSONObject)o; } throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONObject."); } /** * Get the long value associated with a key. If the number value is too * long for a long, it will be clipped. * * @param key A key string. * @return The long value. * @throws JSONException if the key is not found or if the value cannot * be converted to a long. */ public long getLong(String key) throws JSONException { return doGetLong(key, get(key)); } private long doGetLong(String key, Object o) throws JSONException { return o instanceof String ? Long.parseLong(((String)o)) : o instanceof Number ? ((Number)o).longValue() : (long)getDouble(key); } /** * Get the string associated with a key. * * @param key A key string. * @return A string which is the value. * @throws JSONException if the key is not found. */ public String getString(String key) throws JSONException { return get(key).toString(); } /** * Determine if the JSONObject contains a specific key. * @param key A key string. * @return true if the key exists in the JSONObject. */ public boolean has(String key) { return this.myHashMap.containsKey(key); } /** * Determine if the value associated with the key is null or if there is * no value. * @param key A key string. * @return true if there is no value associated with the key or if * the value is the JSONObject.NULL object. */ public boolean isNull(String key) { return JSONObject.NULL.equals(opt(key)) || JSONObject.EXPLICIT_NULL.equals(opt(key)); } /** * Get an enumeration of the keys of the JSONObject. * * @return An iterator of the keys. */ public Iterator keys() { return this.myHashMap.keySet().iterator(); } /** * Get the number of keys stored in the JSONObject. * * @return The number of keys in the JSONObject. */ public int length() { return this.myHashMap.size(); } /** * Produce a JSONArray containing the names of the elements of this * JSONObject. * @return A JSONArray containing the key strings, or null if the JSONObject * is empty. */ public JSONArray names() { JSONArray ja = new JSONArray(); Iterator keys = keys(); while (keys.hasNext()) { ja.put(keys.next()); } return ja.length() == 0 ? null : ja; } /** * Produce a string from a Number. * @param n A Number * @return A String. * @throws JSONException If n is a non-finite number. */ static public String numberToString(Number n) throws JSONException { if (n == null) { throw new JSONException("Null pointer"); } testValidity(n); // Shave off trailing zeros and decimal point, if possible. String s = n.toString(); if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { while (s.endsWith("0")) { s = s.substring(0, s.length() - 1); } if (s.endsWith(".")) { s = s.substring(0, s.length() - 1); } } return s; } /** * Get an optional value associated with a key. * @param key A key string. * @return An object which is the value, or null if there is no value. */ public Object opt(String key) { return key == null ? null : this.myHashMap.get(key); } /** * Get an optional boolean associated with a key. * It returns false if there is no such key, or if the value is not * Boolean.TRUE or the String "true". * * @param key A key string. * @return The truth. */ public boolean optBoolean(String key) { return optBoolean(key, false); } /** * Get an optional boolean associated with a key. * It returns the defaultValue if there is no such key, or if it is not * a Boolean or the String "true" or "false" (case insensitive). * * @param key A key string. * @param defaultValue The default. * @return The truth. */ public boolean optBoolean(String key, boolean defaultValue) { Object o = opt(key); if (o == null) { return defaultValue; } else { try { return doGetBoolean(key, o); } catch (JSONException ex) { throw new RuntimeException(ex); } } } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONArray which is produced from a Collection. * @param key A key string. * @param value A Collection value. * @return this. * @throws JSONException JSONException */ public JSONObject put(String key, Collection value) throws JSONException { put(key, new JSONArray(value)); return this; } /** * Get an optional double associated with a key, * or NaN if there is no such key or if its value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A string which is the key. * @return An object which is the value. */ public double optDouble(String key) { return optDouble(key, Double.NaN); } /** * Get an optional double associated with a key, or the * defaultValue if there is no such key or if its value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public double optDouble(String key, double defaultValue) { Object o = opt(key); if (o == null) { return defaultValue; } else { try { return doGetDouble(key, o); } catch (JSONException ex) { throw new RuntimeException(ex); } } } /** * Get an optional int value associated with a key, * or zero if there is no such key or if the value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A key string. * @return An object which is the value. */ public int optInt(String key) { return optInt(key, 0); } /** * Get an optional int value associated with a key, * or the default if there is no such key or if the value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public int optInt(String key, int defaultValue) { Object o = opt(key); if (o == null) { return defaultValue; } else { try { return doGetInt(key, o); } catch (JSONException ex) { throw new RuntimeException(ex); } } } /** * Get an optional JSONArray associated with a key. * It returns null if there is no such key, or if its value is not a * JSONArray. * * @param key A key string. * @return A JSONArray which is the value. */ public JSONArray optJSONArray(String key) { Object o = opt(key); return o instanceof JSONArray ? (JSONArray)o : null; } /** * Get an optional JSONObject associated with a key. * It returns null if there is no such key, or if its value is not a * JSONObject. * * @param key A key string. * @return A JSONObject which is the value. */ public JSONObject optJSONObject(String key) { Object o = opt(key); return o instanceof JSONObject ? (JSONObject)o : null; } /** * Get an optional long value associated with a key, * or zero if there is no such key or if the value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A key string. * @return An object which is the value. */ public long optLong(String key) { return optLong(key, 0); } /** * Get an optional long value associated with a key, * or the default if there is no such key or if the value is not a number. * If the value is a string, an attempt will be made to evaluate it as * a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public long optLong(String key, long defaultValue) { Object o = opt(key); if (o == null) { return defaultValue; } else { try { return doGetLong(key, o); } catch (JSONException ex) { throw new RuntimeException(ex); } } } /** * Get an optional string associated with a key. * It returns an empty string if there is no such key. If the value is not * a string and is not null, then it is coverted to a string. * * @param key A key string. * @return A string which is the value. */ public String optString(String key) { return optString(key, ""); } /** * Get an optional string associated with a key. * It returns the defaultValue if there is no such key. * * @param key A key string. * @param defaultValue The default. * @return A string which is the value. */ public String optString(String key, String defaultValue) { Object o = opt(key); return o != null ? o.toString() : defaultValue; } /** * Put a key/boolean pair in the JSONObject. * * @param key A key string. * @param value A boolean which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject put(String key, boolean value) throws JSONException { put(key, value ? Boolean.TRUE : Boolean.FALSE); return this; } /** * Put a key/double pair in the JSONObject. * * @param key A key string. * @param value A double which is the value. * @return this. * @throws JSONException If the key is null or if the number is invalid. */ public JSONObject put(String key, double value) throws JSONException { put(key, new Double(value)); return this; } /** * Put a key/int pair in the JSONObject. * * @param key A key string. * @param value An int which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject put(String key, int value) throws JSONException { put(key, Integer.valueOf(value)); return this; } /** * Put a key/long pair in the JSONObject. * * @param key A key string. * @param value A long which is the value. * @return this. * @throws JSONException If the key is null. */ public JSONObject put(String key, long value) throws JSONException { put(key, Long.valueOf(value)); return this; } /** * Put a key/value pair in the JSONObject, where the value will be a * JSONObject which is produced from a Map. * @param key A key string. * @param value A Map value. * @return this. * @throws JSONException JSONException */ public JSONObject put(String key, Map value) throws JSONException { put(key, new JSONObject(value)); return this; } /** * Put a key/value pair in the JSONObject. If the value is null, * then the key will be removed from the JSONObject if it is present. * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, * or the JSONObject.NULL object. * @return this. * @throws JSONException If the value is non-finite number * or if the key is null. */ public JSONObject put(String key, Object value) throws JSONException { return doPut(key, value, -1, false); } protected JSONObject doPut(String key, Object value, int threshold, boolean checkExistingValue) throws JSONException { if (key == null) { throw new JSONException("Null key."); } if (value != null) { testValidity(value); if (!checkExistingValue || !this.myHashMap.containsKey(key)) { this.myHashMap.put(key, value); if (threshold > 0 && myHashMap.size() >= threshold) { throw new JSONSequenceTooLargeException("Threshold has been exceeded"); } } else { JSONArray array = null; Object existingValue = this.myHashMap.get(key); if (existingValue instanceof JSONArray) { array = ((JSONArray)existingValue); } else { array = new JSONArray(Collections.singletonList(existingValue)); this.myHashMap.put(key, array); } array.put(value); } } else if (!writeNullAsString) { this.myHashMap.put(key, null); } else { remove(key); } return this; } /** * Put a key/value pair in the JSONObject, but only if the * key and the value are both non-null. * @param key A key string. * @param value An object which is the value. It should be of one of these * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, * or the JSONObject.NULL object. * @return this. * @throws JSONException If the value is a non-finite number. */ public JSONObject putOpt(String key, Object value) throws JSONException { if (key != null && value != null) { put(key, value); } return this; } /** * Produce a string in double quotes with backslash sequences in all the * right places. A backslash will be inserted within </, allowing JSON * text to be delivered in HTML. In JSON text, a string cannot contain a * control character or an unescaped quote or backslash. * @param string A String * @return A String correctly formatted for insertion in a JSON text. */ public static String quote(String string) { return quote(string, true); } public static String quote(String string, boolean escapeForwardSlashAlways) { if (string == null || string.length() == 0) { return "\"\""; } char c = 0; int i; int len = string.length(); StringBuilder sb = new StringBuilder(len + 4); String t; sb.append('"'); for (i = 0; i < len; i += 1) { c = string.charAt(i); switch (c) { case '\\': sb.append("\\\\"); break; case '"': sb.append("\\\""); break; case '/': if (escapeForwardSlashAlways || i > 0 && string.charAt(i - 1) == '<') { sb.append('\\'); } sb.append(c); break; case '\b': sb.append("\\b"); break; case '\t': sb.append("\\t"); break; case '\n': sb.append("\\n"); break; case '\f': sb.append("\\f"); break; case '\r': sb.append("\\r"); break; case '\u2028': sb.append("\\u2028"); break; case '\u2029': sb.append("\\u2029"); break; default: if (c < ' ') { t = "000" + Integer.toHexString(c); sb.append("\\u" + t.substring(t.length() - 4)); } else { sb.append(c); } } } sb.append('"'); return sb.toString(); } /** * Remove a name and its value, if present. * @param key The name to be removed. * @return The value that was associated with the name, * or null if there was no value. */ public Object remove(String key) { return this.myHashMap.remove(key); } /** * Throw an exception if the object is an NaN or infinite number. * @param o The object to test. * @throws JSONException If o is a non-finite number. */ static void testValidity(Object o) throws JSONException { if (o != null) { if (o instanceof Double) { if (((Double)o).isInfinite() || ((Double)o).isNaN()) { throw new JSONException( "JSON does not allow non-finite numbers"); } } else if (o instanceof Float) { if (((Float)o).isInfinite() || ((Float)o).isNaN()) { throw new JSONException( "JSON does not allow non-finite numbers."); } } } } /** * Produce a JSONArray containing the values of the members of this * JSONObject. * @param names A JSONArray containing a list of key strings. This * determines the sequence of the values in the result. * @return A JSONArray of values. * @throws JSONException If any of the values are non-finite numbers. */ public JSONArray toJSONArray(JSONArray names) throws JSONException { if (names == null || names.length() == 0) { return null; } JSONArray ja = new JSONArray(); for (int i = 0; i < names.length(); i += 1) { ja.put(this.opt(names.getString(i))); } return ja; } @Override public int hashCode() { return myHashMap.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof JSONObject) { return myHashMap.equals(((JSONObject)obj).myHashMap); } else { return false; } } /** * Make a JSON text of this JSONObject. For compactness, no whitespace * is added. If this would not result in a syntactically correct JSON text, * then null will be returned instead. *

* Warning: This method assumes that the data structure is acyclical. * * @return a printable, displayable, portable, transmittable * representation of the object, beginning * with { (left brace) and ending * with } (right brace). */ public String toString() { try { Iterator keys = keys(); StringBuilder sb = new StringBuilder("{"); while (keys.hasNext()) { if (sb.length() > 1) { sb.append(','); } Object o = keys.next(); sb.append(quote(o.toString(), escapeForwardSlashAlways)); sb.append(':'); sb.append(valueToString(this.myHashMap.get(o), escapeForwardSlashAlways)); } sb.append('}'); return sb.toString(); } catch (Exception e) { return null; } } /** * Make a prettyprinted JSON text of this JSONObject. *

* Warning: This method assumes that the data structure is acyclical. * @param indentFactor The number of spaces to add to each level of * indentation. * @return a printable, displayable, portable, transmittable * representation of the object, beginning * with { (left brace) and ending * with } (right brace). * @throws JSONException If the object contains an invalid number. */ public String toString(int indentFactor) throws JSONException { return toString(indentFactor, 0); } /** * Make a prettyprinted JSON text of this JSONObject. *

* Warning: This method assumes that the data structure is acyclical. * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indentation of the top level. * @return a printable, displayable, transmittable * representation of the object, beginning * with { (left brace) and ending * with } (right brace). * @throws JSONException If the object contains an invalid number. */ String toString(int indentFactor, int indent) throws JSONException { int i; int n = length(); if (n == 0) { return "{}"; } Iterator keys = keys(); StringBuilder sb = new StringBuilder("{"); int newindent = indent + indentFactor; while (keys.hasNext()) { Object o = keys.next(); if (sb.length() > 1) { sb.append(",\n"); } else { sb.append('\n'); } for (i = 0; i < newindent; i += 1) { sb.append(' '); } sb.append(quote(o.toString())); sb.append(": "); sb.append(valueToString(this.myHashMap.get(o), indentFactor, newindent, escapeForwardSlashAlways)); } if (sb.length() > 1) { sb.append('\n'); for (i = 0; i < indent; i += 1) { sb.append(' '); } } sb.append('}'); return sb.toString(); } /** * Make a JSON text of an Object value. If the object has an * value.toJSONString() method, then that method will be used to produce * the JSON text. The method is required to produce a strictly * conforming text. If the object does not contain a toJSONString * method (which is the most common case), then a text will be * produced by the rules. *

* Warning: This method assumes that the data structure is acyclical. * @param value The value to be serialized. * @return a printable, displayable, transmittable * representation of the object, beginning * with { (left brace) and ending * with } (right brace). * @throws JSONException If the value is or contains an invalid number. */ static String valueToString(Object value, boolean escapeForwardSlash) throws JSONException { if (value == null || value.equals(null)) { return "null"; } if (value instanceof JSONString) { String o; try { o = ((JSONString)value).toJSONString(); } catch (Exception e) { throw new JSONException(e); } if (o != null) { return o; } throw new JSONException("Bad value from toJSONString: " + o); } if (value instanceof Number) { return numberToString((Number) value); } if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) { return value.toString(); } return quote(value.toString(), escapeForwardSlash); } /** * Make a prettyprinted JSON text of an object value. *

* Warning: This method assumes that the data structure is acyclical. * @param value The value to be serialized. * @param indentFactor The number of spaces to add to each level of * indentation. * @param indent The indentation of the top level. * @return a printable, displayable, transmittable * representation of the object, beginning * with { (left brace) and ending * with } (right brace). * @throws JSONException If the object contains an invalid number. */ static String valueToString(Object value, int indentFactor, int indent, boolean escapeForwardSlash) throws JSONException { if (value == null || value.equals(null)) { return "null"; } try { if (value instanceof JSONString) { return ((JSONString)value).toJSONString(); } } catch (Exception e) { /* forget about it */ } if (value instanceof Number) { return numberToString((Number) value); } if (value instanceof Boolean) { return value.toString(); } if (value instanceof JSONObject) { return ((JSONObject)value).toString(indentFactor, indent); } if (value instanceof JSONArray) { return ((JSONArray)value).toString(indentFactor, indent); } return quote(value.toString(), escapeForwardSlash); } /** * Set the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default * value is 500 * @param newRecursionDepthLimit the new recursion depth limit to set */ public static void setGlobalRecursionDepthLimit(int newRecursionDepthLimit) { RECURSION_DEPTH_LIMIT = newRecursionDepthLimit; } /** * Set the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default * value is 500 * @param newRecursionDepthLimit the new recursion depth limit to set */ @Deprecated public void setRecursionDepthLimit(int newRecursionDepthLimit) { RECURSION_DEPTH_LIMIT = newRecursionDepthLimit; } /** * Get the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default * value is 500 * @return the recursion depth limit */ public static int getGlobalRecursionDepthLimit() { return RECURSION_DEPTH_LIMIT; } /** * Get the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default * value is 500 * @return the recursion depth limit */ @Deprecated public int getRecursionDepthLimit() { return RECURSION_DEPTH_LIMIT; } /** * Write the contents of the JSONObject as JSON text to a writer. * For compactness, no whitespace is added. *

* Warning: This method assumes that the data structure is acyclical. * * @param writer The writer * @return The writer. * @throws JSONException JSONException */ public Writer write(Writer writer) throws JSONException { try { int hashMapSize = this.myHashMap.size(); boolean dropObjectKeyName = false; if (hashMapSize == 1) { dropObjectKeyName = dropRootElement || ignoredElements != null && ignoredElements.contains(keys().next()); } if (!dropObjectKeyName) { writer.write('{'); } boolean b = false; Iterator keys = keys(); while (keys.hasNext()) { if (b) { writer.write(','); b = false; } String k = keys.next().toString(); Object v = this.myHashMap.get(k); boolean mayBeDropSimpleElement = false; if (!dropObjectKeyName) { mayBeDropSimpleElement = hashMapSize > 1 && ignoredElements != null && ignoredElements.contains(k); if (!mayBeDropSimpleElement) { writer.write(quote(k, escapeForwardSlashAlways)); writer.write(':'); } } if (v instanceof JSONObject) { ((JSONObject)v).write(writer); } else if (v instanceof JSONArray) { ((JSONArray)v).write(writer); } else if (!mayBeDropSimpleElement) { writer.write(valueToString(v, escapeForwardSlashAlways)); } if (!mayBeDropSimpleElement) { b = true; } } if (!dropObjectKeyName) { writer.write('}'); } return writer; } catch (IOException e) { throw new JSONException(e); } } public boolean isEscapeForwardSlashAlways() { return escapeForwardSlashAlways; } public void setEscapeForwardSlashAlways(boolean escapeForwardSlashAlways) { this.escapeForwardSlashAlways = escapeForwardSlashAlways; } public Map toMap() { return Collections.unmodifiableMap(myHashMap); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONString.java000066400000000000000000000024501440405772200276540ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; /** * The JSONString interface allows a toJSONString() * method so that a class can change the behavior of * JSONObject.toString(), JSONArray.toString(), * and JSONWriter.value(Object). The * toJSONString method will be used instead of the default behavior * of using the Object's toString() method and quoting the result. */ public interface JSONString { /** * The toJSONString method allows a class to produce its own JSON * serialization. * * @return A strictly syntactically correct JSON text. */ public String toJSONString(); } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONStringer.java000066400000000000000000000051301440405772200302010ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; import java.io.StringWriter; /** * JSONStringer provides a quick and convenient way of producing JSON text. * The texts produced strictly conform to JSON syntax rules. No whitespace is * added, so the results are ready for transmission or storage. Each instance of * JSONStringer can produce one JSON text. *

* A JSONStringer instance provides a value method for appending * values to the * text, and a key * method for adding keys before values in objects. There are array * and endArray methods that make and bound array values, and * object and endObject methods which make and bound * object values. All of these methods return the JSONWriter instance, * permitting cascade style. For example,

 * myString = new JSONStringer()
 *     .object()
 *         .key("JSON")
 *         .value("Hello, World!")
 *     .endObject()
 *     .toString();
which produces the string
 * {"JSON":"Hello, World!"}
*

* The first method called must be array or object. * There are no methods for adding commas or colons. JSONStringer adds them for * you. Objects and arrays can be nested up to 20 levels deep. *

* This can sometimes be easier than using a JSONObject to build a string. * @author JSON.org * @version 2 */ public class JSONStringer extends JSONWriter { /** * Make a fresh JSONStringer. It can be used to build one JSON text. */ public JSONStringer() { super(new StringWriter()); } /** * Return the JSON text. This method is used to obtain the product of the * JSONStringer instance. It will return null if there was a * problem in the construction of the JSON text (such as the calls to * array were not properly balanced with calls to * endArray). * @return The JSON text. */ public String toString() { return this.mode == 'd' ? this.writer.toString() : null; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONTokener.java000066400000000000000000000351321440405772200300200ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; import java.math.BigDecimal; /** * A JSONTokener takes a source string and extracts characters and tokens from * it. It is used by the JSONObject and JSONArray constructors to parse * JSON source strings. * @author JSON.org * @version 2 */ public class JSONTokener { private static final String USE_BIGDECIMAL_JSONTOKENER_KEY = "jettison.json.jsontokener.use_bigdecimal"; public static final boolean USE_BIGDECIMAL_JSONTOKENER = Boolean.getBoolean( USE_BIGDECIMAL_JSONTOKENER_KEY ); protected boolean useBigDecimal = USE_BIGDECIMAL_JSONTOKENER; /** * The index of the next character. */ private int myIndex; /** * The source string being tokenized. */ private String mySource; private int threshold = -1; private int recursionDepth; /** * Construct a JSONTokener from a string. * * @param s A source string. */ public JSONTokener(String s) { this.myIndex = 0; this.mySource = s.trim(); } /** * Construct a JSONTokener from a string. * * @param s A source string. * @param threshold A source threshold. */ public JSONTokener(String s, int threshold) { this.myIndex = 0; this.mySource = s.trim(); this.threshold = threshold; } public int getThreshold() { return threshold; } /** * Back up one character. This provides a sort of lookahead capability, * so that you can test for a digit or letter before attempting to parse * the next number or identifier. */ public void back() { if (this.myIndex > 0) { this.myIndex -= 1; } } /** * Get the hex value of a character (base16). * @param c A character between '0' and '9' or between 'A' and 'F' or * between 'a' and 'f'. * @return An int between 0 and 15, or -1 if c was not a hex digit. */ public static int dehexchar(char c) { if (c >= '0' && c <= '9') { return c - '0'; } if (c >= 'A' && c <= 'F') { return c - ('A' - 10); } if (c >= 'a' && c <= 'f') { return c - ('a' - 10); } return -1; } /** * Determine if the source string still contains characters that next() * can consume. * @return true if not yet at the end of the source. */ public boolean more() { return this.myIndex < this.mySource.length(); } /** * Get the next character in the source string. * * @return The next character, or 0 if past the end of the source string. */ public char next() { if (more()) { char c = this.mySource.charAt(this.myIndex); this.myIndex += 1; return c; } return 0; } /** * Consume the next character, and check that it matches a specified * character. * @param c The character to match. * @return The character. * @throws JSONException if the character does not match. */ public char next(char c) throws JSONException { char n = next(); if (n != c) { throw syntaxError("Expected '" + c + "' and instead saw '" + n + "'."); } return n; } /** * Get the next n characters. * * @param n The number of characters to take. * @return A string of n characters. * @throws JSONException * Substring bounds error if there are not * n characters remaining in the source string. */ public String next(int n) throws JSONException { int i = this.myIndex; int j = i + n; if (j >= this.mySource.length()) { throw syntaxError("Substring bounds error"); } this.myIndex += n; return this.mySource.substring(i, j); } /** * Get the next char in the string, skipping whitespace * and comments (slashslash, slashstar, and hash). * @throws JSONException JSONException * @return A character, or 0 if there are no more characters. */ public char nextClean() throws JSONException { for (;;) { char c = next(); if (c == '/') { switch (next()) { case '/': do { c = next(); } while (c != '\n' && c != '\r' && c != 0); break; case '*': for (;;) { c = next(); if (c == 0) { throw syntaxError("Unclosed comment."); } if (c == '*') { if (next() == '/') { break; } } } break; default: if (!more()) { throw syntaxError("The JSON text is malformed"); } back(); return '/'; } } else if (c == '#') { do { c = next(); } while (c != '\n' && c != '\r' && c != 0); } else if (c == 0 || c > ' ') { return c; } } } /** * Return the characters up to the next close quote character. * Backslash processing is done. The formal JSON format does not * allow strings in single quotes, but an implementation is allowed to * accept them. * @param quote The quoting character, either * " (double quote) or * ' (single quote). * @return A String. * @throws JSONException Unterminated string. */ public String nextString(char quote) throws JSONException { char c; StringBuilder sb = new StringBuilder(); for (;;) { c = next(); switch (c) { case 0: case '\n': case '\r': throw syntaxError("Unterminated string"); case '\\': c = next(); switch (c) { case 'b': sb.append('\b'); break; case 't': sb.append('\t'); break; case 'n': sb.append('\n'); break; case 'f': sb.append('\f'); break; case 'r': sb.append('\r'); break; case 'u': sb.append((char)Integer.parseInt(next(4), 16)); break; case 'x' : sb.append((char) Integer.parseInt(next(2), 16)); break; default: sb.append(c); } break; default: if (c == quote) { return sb.toString(); } sb.append(c); } } } /** * Get the text up but not including the specified character or the * end of line, whichever comes first. * @param d A delimiter character. * @return A string. */ public String nextTo(char d) { StringBuilder sb = new StringBuilder(); for (;;) { char c = next(); if (c == d || c == 0 || c == '\n' || c == '\r') { if (c != 0) { back(); } return sb.toString().trim(); } sb.append(c); } } /** * Get the text up but not including one of the specified delimeter * characters or the end of line, whichever comes first. * @param delimiters A set of delimiter characters. * @return A string, trimmed. */ public String nextTo(String delimiters) { char c; StringBuilder sb = new StringBuilder(); for (;;) { c = next(); if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') { if (c != 0) { back(); } return sb.toString().trim(); } sb.append(c); } } /** * Get the next value. The value can be a Boolean, Double/BigDecimal * (depending on -Djettison.json.jsontokener.use_bigdecimal), Integer, * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. * @throws JSONException If syntax error. * * @return An object. */ public Object nextValue() throws JSONException { char c = nextClean(); String s; switch (c) { case '"': case '\'': return nextString(c); case '{': back(); return newJSONObject(); case '[': back(); return newJSONArray(); } /* * Handle unquoted text. This could be the values true, false, or * null, or it can be a number. An implementation (such as this one) * is allowed to also accept non-standard forms. * * Accumulate characters until we reach the end of the text or a * formatting character. */ StringBuilder sb = new StringBuilder(); char b = c; while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { sb.append(c); c = next(); } back(); /* * If it is true, false, or null, return the proper value. */ s = sb.toString().trim(); if (s.equals("")) { throw syntaxError("Missing value."); } if (s.equalsIgnoreCase("true")) { return Boolean.TRUE; } if (s.equalsIgnoreCase("false")) { return Boolean.FALSE; } if (s.equalsIgnoreCase("null")) { return JSONObject.EXPLICIT_NULL; } /* * If it might be a number, try converting it. We support the 0- and 0x- * conventions. If a number cannot be produced, then the value will just * be a string. Note that the 0-, 0x-, plus, and implied string * conventions are non-standard. A JSON parser is free to accept * non-JSON forms as long as it accepts all correct JSON forms. */ if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { if (b == '0') { if (s.length() > 2 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { try { return Integer.valueOf(Integer.parseInt(s.substring(2), 16)); } catch (Exception e) { /* Ignore the error */ } } else { try { return Integer.valueOf(Integer.parseInt(s, 8)); } catch (Exception e) { /* Ignore the error */ } } } try { return Integer.valueOf(s); } catch (Exception e) { try { return Long.valueOf(s); } catch (Exception f) { try { if (useBigDecimal) { return new BigDecimal(s); } else { return new Double(s); } } catch (Exception g) { return s; } } } } return s; } protected JSONObject newJSONObject() throws JSONException { checkRecursionDepth(); JSONObject object = new JSONObject(this); recursionDepth--; return object; } protected JSONArray newJSONArray() throws JSONException { checkRecursionDepth(); JSONArray array = new JSONArray(this); recursionDepth--; return array; } private void checkRecursionDepth() throws JSONException { recursionDepth++; if (recursionDepth > JSONObject.RECURSION_DEPTH_LIMIT) { throw new JSONException("JSONTokener has reached recursion depth limit of " + JSONObject.RECURSION_DEPTH_LIMIT); } } /** * Skip characters until the next character is the requested character. * If the requested character is not found, no characters are skipped. * @param to A character to skip to. * @return The requested character, or zero if the requested character * is not found. */ public char skipTo(char to) { char c; int index = this.myIndex; do { c = next(); if (c == 0) { this.myIndex = index; return c; } } while (c != to); back(); return c; } /** * Skip characters until past the requested string. * If it is not found, we are left at the end of the source. * @param to A string to skip past. */ public void skipPast(String to) { this.myIndex = this.mySource.indexOf(to, this.myIndex); if (this.myIndex < 0) { this.myIndex = this.mySource.length(); } else { this.myIndex += to.length(); } } /** * Make a JSONException to signal a syntax error. * * @param message The error message. * @return A JSONException object, suitable for throwing */ public JSONException syntaxError(String message) { return new JSONException(message + toString(), 0, myIndex); } /** * Make a printable string of this JSONTokener. * * @return " at character [this.myIndex] of [this.mySource]" */ public String toString() { return " at character " + this.myIndex + " of " + this.mySource; } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/json/JSONWriter.java000066400000000000000000000234601440405772200276660ustar00rootroot00000000000000/* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.codehaus.jettison.json; import java.io.IOException; import java.io.Writer; /* Copyright (c) 2002 JSON.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * JSONWriter provides a quick and convenient way of producing JSON text. * The texts produced strictly conform to JSON syntax rules. No whitespace is * added, so the results are ready for transmission or storage. Each instance of * JSONWriter can produce one JSON text. *

* A JSONWriter instance provides a value method for appending * values to the * text, and a key * method for adding keys before values in objects. There are array * and endArray methods that make and bound array values, and * object and endObject methods which make and bound * object values. All of these methods return the JSONWriter instance, * permitting a cascade style. For example,

 * new JSONWriter(myWriter)
 *     .object()
 *         .key("JSON")
 *         .value("Hello, World!")
 *     .endObject();
which writes
 * {"JSON":"Hello, World!"}
*

* The first method called must be array or object. * There are no methods for adding commas or colons. JSONWriter adds them for * you. Objects and arrays can be nested up to 20 levels deep. *

* This can sometimes be easier than using a JSONObject to build a string. * @author JSON.org * @version 2 */ public class JSONWriter { private static final int maxdepth = 20; /** * The comma flag determines if a comma should be output before the next * value. */ private boolean comma; /** * The current mode. Values: * 'a' (array), * 'd' (done), * 'i' (initial), * 'k' (key), * 'o' (object). */ protected char mode; /** * The object/array stack. */ private char stack[]; /** * The stack top index. A value of 0 indicates that the stack is empty. */ private int top; /** * The writer that will receive the output. */ protected Writer writer; /** * Make a fresh JSONWriter. It can be used to build one JSON text. * @param w writer */ public JSONWriter(Writer w) { this.comma = false; this.mode = 'i'; this.stack = new char[maxdepth]; this.top = 0; this.writer = w; } /** * Append a value. * @param s A string value. * @return this * @throws JSONException If the value is out of sequence. */ private JSONWriter append(String s) throws JSONException { if (s == null) { throw new JSONException("Null pointer"); } if (this.mode == 'o' || this.mode == 'a') { try { if (this.comma && this.mode == 'a') { this.writer.write(','); } this.writer.write(s); } catch (IOException e) { throw new JSONException(e); } if (this.mode == 'o') { this.mode = 'k'; } this.comma = true; return this; } throw new JSONException("Value out of sequence."); } /** * Begin appending a new array. All values until the balancing * endArray will be appended to this array. The * endArray method must be called to mark the array's end. * @return this * @throws JSONException If the nesting is too deep, or if the object is * started in the wrong place (for example as a key or after the end of the * outermost array or object). */ public JSONWriter array() throws JSONException { if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { this.push('a'); this.append("["); this.comma = false; return this; } throw new JSONException("Misplaced array."); } /** * End something. * @param m Mode * @param c Closing character * @return this * @throws JSONException If unbalanced. */ private JSONWriter end(char m, char c) throws JSONException { if (this.mode != m) { throw new JSONException(m == 'o' ? "Misplaced endObject." : "Misplaced endArray."); } this.pop(m); try { this.writer.write(c); } catch (IOException e) { throw new JSONException(e); } this.comma = true; return this; } /** * End an array. This method most be called to balance calls to * array. * @return this * @throws JSONException If incorrectly nested. */ public JSONWriter endArray() throws JSONException { return this.end('a', ']'); } /** * End an object. This method most be called to balance calls to * object. * @return this * @throws JSONException If incorrectly nested. */ public JSONWriter endObject() throws JSONException { return this.end('k', '}'); } /** * Append a key. The key will be associated with the next value. In an * object, every value must be preceded by a key. * @param s A key string. * @return this * @throws JSONException If the key is out of place. For example, keys * do not belong in arrays or if the key is null. */ public JSONWriter key(String s) throws JSONException { if (s == null) { throw new JSONException("Null key."); } if (this.mode == 'k') { try { if (this.comma) { this.writer.write(','); } this.writer.write(JSONObject.quote(s)); this.writer.write(':'); this.comma = false; this.mode = 'o'; return this; } catch (IOException e) { throw new JSONException(e); } } throw new JSONException("Misplaced key."); } /** * Begin appending a new object. All keys and values until the balancing * endObject will be appended to this object. The * endObject method must be called to mark the object's end. * @return this * @throws JSONException If the nesting is too deep, or if the object is * started in the wrong place (for example as a key or after the end of the * outermost array or object). */ public JSONWriter object() throws JSONException { if (this.mode == 'i') { this.mode = 'o'; } if (this.mode == 'o' || this.mode == 'a') { this.append("{"); this.push('k'); this.comma = false; return this; } throw new JSONException("Misplaced object."); } /** * Pop an array or object scope. * @param c The scope to close. * @throws JSONException If nesting is wrong. */ private void pop(char c) throws JSONException { if (this.top <= 0 || this.stack[this.top - 1] != c) { throw new JSONException("Nesting error."); } this.top -= 1; this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1]; } /** * Push an array or object scope. * @param c The scope to open. * @throws JSONException If nesting is too deep. */ private void push(char c) throws JSONException { if (this.top >= maxdepth) { throw new JSONException("Nesting too deep."); } this.stack[this.top] = c; this.mode = c; this.top += 1; } /** * Append either the value true or the value * false. * @param b A boolean. * @return this * @throws JSONException JSONException */ public JSONWriter value(boolean b) throws JSONException { return this.append(b ? "true" : "false"); } /** * Append a double value. * @param d A double. * @return this * @throws JSONException If the number is not finite. */ public JSONWriter value(double d) throws JSONException { return this.value(new Double(d)); } /** * Append a long value. * @param l A long. * @return this * @throws JSONException JSONException */ public JSONWriter value(long l) throws JSONException { return this.append(Long.toString(l)); } /** * Append an object value. * @param o The object to append. It can be null, or a Boolean, Number, * String, JSONObject, or JSONArray, or an object with a toJSONString() * method. * @return this * @throws JSONException If the value is out of sequence. */ public JSONWriter value(Object o) throws JSONException { return this.append(JSONObject.valueToString(o, true)); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/000077500000000000000000000000001440405772200253455ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/Configuration.java000066400000000000000000000154451440405772200310300ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class Configuration { /* Were there a constants class, this key would live there. */ private static final String JETTISON_TYPE_CONVERTER_CLASS_KEY = "jettison.mapped.typeconverter.class"; /* Mostly exists to wrap exception handling for reflective invocations. */ private static class ConverterFactory { TypeConverter newDefaultConverterInstance() { return new DefaultConverter(); } } private static final ConverterFactory converterFactory; static { ConverterFactory cf = null; String userSpecifiedClass = System.getProperty( JETTISON_TYPE_CONVERTER_CLASS_KEY ); if( userSpecifiedClass != null && userSpecifiedClass.length() > 0 ) { try { final Class tc = Class.forName( userSpecifiedClass ).asSubclass( TypeConverter.class ); tc.newInstance(); /* Blow up as soon as possible. */ cf = new ConverterFactory() { public TypeConverter newDefaultConverterInstance() { try { return tc.newInstance(); } catch ( Exception e ){ // Implementer of custom class would have to try pretty hard to make this happen, // since we already created one instance. throw new ExceptionInInitializerError( e ); } } }; } catch ( Exception e ){ throw new ExceptionInInitializerError( e ); } } if( cf == null ){ cf = new ConverterFactory(); } converterFactory = cf; } private Map xmlToJsonNamespaces; private List attributesAsElements; private List ignoredElements; private boolean supressAtAttributes; private String attributeKey = "@"; private boolean ignoreNamespaces; private boolean dropRootElement; private boolean rootElementArrayWrapper = true; private Set primitiveArrayKeys = Collections.EMPTY_SET; private boolean writeNullAsString = true; private boolean readNullAsString; private boolean ignoreEmptyArrayValues; private boolean escapeForwardSlashAlways; private String jsonNamespaceSeparator; private TypeConverter typeConverter = converterFactory.newDefaultConverterInstance(); public Configuration() { super(); this.xmlToJsonNamespaces = new HashMap(); } public Configuration(Map xmlToJsonNamespaces) { super(); this.xmlToJsonNamespaces = xmlToJsonNamespaces; } public Configuration(Map xmlToJsonNamespaces, List attributesAsElements, List ignoredElements) { super(); this.xmlToJsonNamespaces = xmlToJsonNamespaces; this.attributesAsElements = attributesAsElements; this.ignoredElements = ignoredElements; } public boolean isIgnoreNamespaces() { return ignoreNamespaces; } public void setIgnoreNamespaces( boolean ignoreNamespaces ) { this.ignoreNamespaces = ignoreNamespaces; } public List getAttributesAsElements() { return attributesAsElements; } public void setAttributesAsElements(List attributesAsElements) { this.attributesAsElements = attributesAsElements; } public List getIgnoredElements() { return ignoredElements; } public void setIgnoredElements(List ignoredElements) { this.ignoredElements = ignoredElements; } public Map getXmlToJsonNamespaces() { return xmlToJsonNamespaces; } public void setXmlToJsonNamespaces(Map xmlToJsonNamespaces) { this.xmlToJsonNamespaces = xmlToJsonNamespaces; } public TypeConverter getTypeConverter() { return typeConverter; } public void setTypeConverter(TypeConverter typeConverter) { this.typeConverter = typeConverter; } public boolean isSupressAtAttributes() { return this.supressAtAttributes; } public void setSupressAtAttributes(boolean supressAtAttributes) { this.supressAtAttributes = supressAtAttributes; } public String getAttributeKey() { return this.attributeKey; } public void setAttributeKey(String attributeKey) { this.attributeKey = attributeKey; } static TypeConverter newDefaultConverterInstance() { return converterFactory.newDefaultConverterInstance(); } public Set getPrimitiveArrayKeys() { return primitiveArrayKeys; } public void setPrimitiveArrayKeys(Set primitiveArrayKeys) { this.primitiveArrayKeys = primitiveArrayKeys; } public boolean isDropRootElement() { return dropRootElement; } public void setDropRootElement(boolean dropRootElement) { this.dropRootElement = dropRootElement; } public boolean isRootElementArrayWrapper() { return rootElementArrayWrapper; } public void setRootElementArrayWrapper(boolean rootElementArrayWrapper) { this.rootElementArrayWrapper = rootElementArrayWrapper; } public boolean isWriteNullAsString() { return writeNullAsString; } public void setWriteNullAsString(boolean writeNullAsString) { this.writeNullAsString = writeNullAsString; } public boolean isReadNullAsString() { return readNullAsString; } public void setReadNullAsString(boolean readNullString) { this.readNullAsString = readNullString; } public boolean isIgnoreEmptyArrayValues() { return ignoreEmptyArrayValues; } public void setIgnoreEmptyArrayValues(boolean ignoreEmptyArrayValues) { this.ignoreEmptyArrayValues = ignoreEmptyArrayValues; } @Deprecated public void setReadNullAsEmptyString(boolean read) { } public boolean isEscapeForwardSlashAlways() { return escapeForwardSlashAlways; } public void setEscapeForwardSlashAlways(boolean escapeForwardSlash) { this.escapeForwardSlashAlways = escapeForwardSlash; } public String getJsonNamespaceSeparator() { return jsonNamespaceSeparator; } public void setJsonNamespaceSeparator(String jsonNamespaceSeparator) { this.jsonNamespaceSeparator = jsonNamespaceSeparator; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/DefaultConverter.java000066400000000000000000000153541440405772200314740ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; /** * Default converter that tries to convert value to appropriate primitive (if fails, returns original string) * * @author Dejan Bosanac * @since 1.1 */ public class DefaultConverter implements TypeConverter { /* Were there a constants class, this key would live there. */ private static final String ENFORCE_32BIT_INTEGER_KEY = "jettison.mapped.typeconverter.enforce_32bit_integer"; public static final boolean ENFORCE_32BIT_INTEGER = Boolean.getBoolean( ENFORCE_32BIT_INTEGER_KEY ); private boolean enforce32BitInt = ENFORCE_32BIT_INTEGER; public void setEnforce32BitInt(boolean enforce32BitInt) { this.enforce32BitInt = enforce32BitInt; } public Object convertToJSONPrimitive(String text) { if(text == null) return text; // If there's at least one character if (text.length() >= 1) { // find the first character char first = text.charAt(0); // Is it incompatible with a number? if ((first < '0' || first > '9') && first != '-') { // Yes it is, so special case check for Boolean values if (first == 't') { if (text.equals("true")) { return Boolean.TRUE; } } else if (first == 'f') { if (text.equals("false")) { return Boolean.FALSE; } } // Definitely not a Boolean or a number, so return the original value return text; } } Object primitive = null; if (enforce32BitInt) { primitive = getInteger(text); } else { primitive = getLong(text); } if (primitive == null) { Double dbl = getDouble(text); if (dbl != null) { if (dbl.isInfinite() || dbl.isNaN()) { primitive = text; } else { primitive = dbl; } } } if (primitive == null || !primitive.toString().equals(text)) { // Default String primitive = text; } return primitive; } private static final int MAX_LENGTH_LONG = String.valueOf(Long.MAX_VALUE).length(); private static final int MAX_LENGTH_LONG_NEGATIVE = String.valueOf(Long.MAX_VALUE).length() + 1; /** * Try to get a Long value efficiently, avoiding Exceptions */ private static Long getLong(String text) { // handle an empty string if (text.isEmpty()) return null; // if the text is too long it can't be a Long if (text.charAt(0) == '-') { if (text.length() > MAX_LENGTH_LONG_NEGATIVE) { return null; } } else if (text.length() > MAX_LENGTH_LONG) { return null; } // Handle a leading minus sign int i = 0; if (text.charAt(0) == '-') { if (text.length() > 1) { i++; } else { return null; } } // Check each character is a digit for (; i < text.length(); i++) { if (!Character.isDigit(text.charAt(i))) { return null; } } // It looks like it might be a Long, so give it a go try { return Long.parseLong(text); } catch (Exception e) { // It isn't a Long return null; } } private static final int MAX_LENGTH_INTEGER = String.valueOf(Integer.MAX_VALUE).length(); private static final int MAX_LENGTH_INTEGER_NEGATIVE = String.valueOf(Integer.MAX_VALUE).length() + 1; /** * Try to get an Integer value efficiently, avoiding Exceptions */ private static Integer getInteger(String text) { // handle an empty string if (text.isEmpty()) return null; // if the text is too long it can't be an Integer if (text.charAt(0) == '-') { if (text.length() > MAX_LENGTH_INTEGER_NEGATIVE) { return null; } } else if (text.length() > MAX_LENGTH_INTEGER) { return null; } // Handle a leading minus sign int i = 0; if (text.charAt(0) == '-') { if (text.length() > 1) { i++; } else { return null; } } // Check each character is a digit for (; i < text.length(); i++) { if (!Character.isDigit(text.charAt(i))) { return null; } } // It looks like it might be an Integer, so give it a go try { return Integer.parseInt(text); } catch (Exception e) { // It isn't an Integer return null; } } /** * Try to get a Double value efficiently, avoiding Exceptions */ private static Double getDouble(String text) { boolean foundDP = false; boolean foundExp = false; // handle an empty string if (text.isEmpty()) return null; // Handle a leading minus sign int i = 0; if (text.charAt(0) == '-') { if (text.length() > 1) i++; else return null; } // Check each character is a digit for (; i < text.length(); i++) { char next = text.charAt(i); if (!Character.isDigit(next)) { if (next == '.') { if (foundDP) return null; foundDP = true; } else if (next == 'E' || next == 'e') { if (foundExp) return null; foundExp = true; } else return null; } } // It looks like it might be a Double, so give it a go try { return Double.parseDouble(text); } catch (Exception e) { // It isn't a Double return null; } } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedDOMDocumentParser.java000066400000000000000000000020501440405772200326270ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.util.HashMap; import org.codehaus.jettison.AbstractDOMDocumentParser; /** * JSON Mapped DOM parser * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class MappedDOMDocumentParser extends AbstractDOMDocumentParser { public MappedDOMDocumentParser(Configuration con) { super(new MappedXMLInputFactory(con)); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedDOMDocumentSerializer.java000066400000000000000000000021371440405772200335120ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.OutputStream; import org.codehaus.jettison.AbstractDOMDocumentSerializer; /** * JSON Mapped DOM serializer * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class MappedDOMDocumentSerializer extends AbstractDOMDocumentSerializer { public MappedDOMDocumentSerializer(OutputStream output, Configuration con) { super(output, new MappedXMLOutputFactory(con)); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedNamespaceConvention.java000066400000000000000000000331431440405772200333020ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import org.codehaus.jettison.Convention; import org.codehaus.jettison.Node; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; /** * * */ public class MappedNamespaceConvention implements Convention, NamespaceContext { private static final String DOT_NAMESPACE_SEP = "."; private Map xnsToJns = new HashMap(); private Map jnsToXns = new HashMap(); private List attributesAsElements; private List ignoredElements; private List jsonAttributesAsElements; private boolean supressAtAttributes; private boolean ignoreNamespaces; private String attributeKey = "@"; private TypeConverter typeConverter; private Set primitiveArrayKeys; private boolean dropRootElement; private boolean writeNullAsString = true; private boolean rootElementArrayWrapper = true; private boolean ignoreEmptyArrayValues; private boolean readNullAsString; private boolean escapeForwardSlashAlways; private String jsonNamespaceSeparator; public MappedNamespaceConvention() { super(); typeConverter = Configuration.newDefaultConverterInstance(); } public MappedNamespaceConvention(Configuration config) { super(); this.xnsToJns = config.getXmlToJsonNamespaces(); this.attributesAsElements = config.getAttributesAsElements(); this.supressAtAttributes = config.isSupressAtAttributes(); this.ignoreNamespaces = config.isIgnoreNamespaces(); this.dropRootElement = config.isDropRootElement(); this.rootElementArrayWrapper = config.isRootElementArrayWrapper(); this.attributeKey = config.getAttributeKey(); this.primitiveArrayKeys = config.getPrimitiveArrayKeys(); this.ignoredElements = config.getIgnoredElements(); this.ignoreEmptyArrayValues = config.isIgnoreEmptyArrayValues(); this.escapeForwardSlashAlways = config.isEscapeForwardSlashAlways(); this.jsonNamespaceSeparator = config.getJsonNamespaceSeparator(); for (Iterator> itr = xnsToJns.entrySet().iterator(); itr.hasNext();) { Map.Entry entry = itr.next(); jnsToXns.put((String)entry.getValue(), entry.getKey()); } jsonAttributesAsElements = new ArrayList(); if (attributesAsElements != null) { for (Iterator itr = attributesAsElements.iterator(); itr.hasNext();) { QName q = (QName) itr.next(); jsonAttributesAsElements.add(createAttributeKey(q.getPrefix(), q.getNamespaceURI(), q.getLocalPart())); } } this.readNullAsString = config.isReadNullAsString(); this.writeNullAsString = config.isWriteNullAsString(); typeConverter = config.getTypeConverter(); if (!writeNullAsString && typeConverter != null) { typeConverter = new NullStringConverter(typeConverter); } } /* (non-Javadoc) * @see org.codehaus.xson.mapped.Convention#processNamespaces(org.codehaus.xson.Node, org.json.JSONObject) */ public void processAttributesAndNamespaces( Node n, JSONObject object ) throws JSONException { // Read in the attributes, and stop when there are no more for (Iterator itr = object.keys(); itr.hasNext();) { String k = (String) itr.next(); if ( this.supressAtAttributes ) { if ( k.startsWith( attributeKey ) ) { k = k.substring( 1 ); } if ( null == this.jsonAttributesAsElements ) { this.jsonAttributesAsElements = new ArrayList(); } if ( !this.jsonAttributesAsElements.contains( k ) ) { this.jsonAttributesAsElements.add( k ); } } if ( k.startsWith( attributeKey ) ) { Object o = object.opt( k ); // String value = object.optString( k ); k = k.substring( 1 ); if ( k.equals( "xmlns" ) ) { // if its a string its a default namespace if ( o instanceof JSONObject ) { JSONObject jo = (JSONObject) o; for (Iterator pitr = jo.keys(); pitr.hasNext();) { // set namespace if one is specified on this attribute. String prefix = (String) pitr.next(); String uri = jo.getString( prefix ); // if ( prefix.equals( "$" ) ) { // prefix = ""; // } n.setNamespace( prefix, uri ); } } // With the 1.0 release, the default behavior was to treat an @xmlns // JSON field name (without a namespace prefix), as the attribute for // the default namespace URI. During JSON->XML serialization, this // default behavior resulted in an xmlns (without a namespace prefix) // attribute appearing on the applicable element, with the default // namespace uri as it's value. // // The code refactoring in this processAttributesAndNamespaces // method back in the 2.0 release, no longer assigns the default // namespace URI to the xmlns (without a namespace prefix) during JSON->XML // serialization, which in some cases is causing unmarshaling issues. // Putting in the following conditional check, restores the previous // default behavior, without breaking anything added during the earlier // refactoring exercise. if (o instanceof String) { String uri = o.toString(); QName name = new QName( XMLConstants.DEFAULT_NS_PREFIX, k); n.setAttribute(name, uri); } } else { String strValue = o == null ? null : o.toString(); QName name = null; // note that a non-prefixed attribute name implies NO namespace, // i.e. as opposed to the in-scope default namespace if ( k.contains( getNamespaceSeparator() ) ) { name = createQName( k, n ); } else { name = new QName( XMLConstants.DEFAULT_NS_PREFIX, k ); } n.setAttribute( name, strValue ); } itr.remove(); } else { // set namespace if one is specified on this attribute. int dot = k.lastIndexOf( getNamespaceSeparator() ); if ( dot != -1 ) { String jns = k.substring( 0, dot ); String xns = getNamespaceURI( jns ); n.setNamespace( "", xns ); } } } } /* * (non-Javadoc) * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(java.lang.String) */ public String getNamespaceURI( String prefix ) { if ( ignoreNamespaces ) { return ""; } else { return (String) jnsToXns.get( prefix ); } } /* * (non-Javadoc) * @see javax.xml.namespace.NamespaceContext#getPrefix(java.lang.String) */ public String getPrefix( String namespaceURI ) { if ( ignoreNamespaces ) { return ""; } else { return (String) xnsToJns.get( namespaceURI ); } } public Iterator getPrefixes( String arg0 ) { if ( ignoreNamespaces ) { return Collections.emptySet().iterator(); } else { return jnsToXns.keySet().iterator(); } } public QName createQName( String rootName, Node node ) { return createQName( rootName ); } @SuppressWarnings("unused") private void readAttribute( Node n, String k, JSONArray array ) throws JSONException { for (int i = 0; i < array.length(); i++) { readAttribute( n, k, array.getString( i ) ); } } private void readAttribute( Node n, String name, String value ) throws JSONException { QName qname = createQName( name ); n.getAttributes().put( qname, value ); } private QName createQName( String name ) { String nsSeparator = getNamespaceSeparator(); int dot = name.lastIndexOf( nsSeparator ); QName qname = null; String local = name; if ( dot == -1 ) { dot = 0; } else { local = local.substring( dot + nsSeparator.length() ); } String jns = name.substring( 0, dot ); String xns = (String) getNamespaceURI( jns ); if ( xns == null ) { qname = new QName( name ); } else { qname = new QName( xns, local ); } return qname; } public String createAttributeKey( String p, String ns, String local ) { StringBuilder builder = new StringBuilder(); if ( !this.supressAtAttributes ) { builder.append( attributeKey ); } String jns = getJSONNamespace(p, ns); // String jns = getPrefix(ns); if ( jns != null && jns.length() != 0 ) { builder.append( jns ).append( getNamespaceSeparator() ); } return builder.append( local ).toString(); } private String getJSONNamespace(String providedPrefix, String ns ) { if ( ns == null || ns.length() == 0 || ignoreNamespaces ) return ""; String jns = (String) xnsToJns.get( ns ); if (jns == null && providedPrefix != null && providedPrefix.length() > 0) { jns = providedPrefix; } if ( jns == null ) { throw new IllegalStateException( "Invalid JSON namespace: " + ns ); } return jns; } public String createKey( String p, String ns, String local ) { StringBuilder builder = new StringBuilder(); String jns = getJSONNamespace(p, ns); // String jns = getPrefix(ns); if ( jns != null && jns.length() != 0 ) { builder.append( jns ).append( getNamespaceSeparator() ); } return builder.append( local ).toString(); } public boolean isElement( String p, String ns, String local ) { if ( attributesAsElements == null ) return false; for (Iterator itr = attributesAsElements.iterator(); itr.hasNext();) { QName q = (QName) itr.next(); if ( q.getNamespaceURI().equals( ns ) && q.getLocalPart().equals( local ) ) { return true; } } return false; } public Object convertToJSONPrimitive( String text ) { return typeConverter.convertToJSONPrimitive( text ); } public Set getPrimitiveArrayKeys() { return primitiveArrayKeys; } public boolean isDropRootElement() { return dropRootElement; } public boolean isRootElementArrayWrapper() { return rootElementArrayWrapper; } public List getIgnoredElements() { return ignoredElements; } public boolean isWriteNullAsString() { return writeNullAsString; } public boolean isReadNullAsString() { return readNullAsString; } public boolean isIgnoreEmptyArrayValues() { return ignoreEmptyArrayValues; } public boolean isEscapeForwardSlashAlways() { return escapeForwardSlashAlways; } public void setEscapeForwardSlashAlways(boolean escapeForwardSlash) { this.escapeForwardSlashAlways = escapeForwardSlash; } public String getNamespaceSeparator() { return jsonNamespaceSeparator == null ? DOT_NAMESPACE_SEP : jsonNamespaceSeparator; } private static class NullStringConverter implements TypeConverter { private static final String NULL_STRING = "null"; private TypeConverter converter; public NullStringConverter(TypeConverter converter) { this.converter = converter; } public Object convertToJSONPrimitive(String text) { if (text != null && NULL_STRING.equals(text)) { return null; } return converter.convertToJSONPrimitive(text); } } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedXMLInputFactory.java000066400000000000000000000051161440405772200323520ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.util.Map; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.codehaus.jettison.AbstractXMLInputFactory; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONTokener; public class MappedXMLInputFactory extends AbstractXMLInputFactory { private MappedNamespaceConvention convention; public MappedXMLInputFactory(Map nstojns) { this(new Configuration(nstojns)); } public MappedXMLInputFactory(Configuration config) { this.convention = new MappedNamespaceConvention(config); } public XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException { try { JSONObject root = createJSONObject(tokener); return new MappedXMLStreamReader(root, convention); } catch (JSONException e) { int column = e.getColumn(); if (column == -1) { throw new XMLStreamException(e); } else { throw new XMLStreamException(e.getMessage(), new ErrorLocation(e.getLine(), e.getColumn()), e); } } } protected JSONObject createJSONObject(JSONTokener tokener) throws JSONException { return new JSONObject(tokener); } private static class ErrorLocation implements Location { private int line = -1; private int column = -1; public ErrorLocation(int line, int column) { this.line = line; this.column = column; } public int getCharacterOffset() { return 0; } public int getColumnNumber() { return column; } public int getLineNumber() { return line; } public String getPublicId() { return null; } public String getSystemId() { return null; } } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedXMLOutputFactory.java000066400000000000000000000025101440405772200325460ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.Writer; import java.util.Map; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.codehaus.jettison.AbstractXMLOutputFactory; public class MappedXMLOutputFactory extends AbstractXMLOutputFactory { private MappedNamespaceConvention convention; public MappedXMLOutputFactory(Map nstojns) { this(new Configuration(nstojns)); } public MappedXMLOutputFactory(Configuration config) { this.convention = new MappedNamespaceConvention(config); } public XMLStreamWriter createXMLStreamWriter(Writer writer) throws XMLStreamException { return new MappedXMLStreamWriter(convention, writer); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedXMLStreamReader.java000066400000000000000000000223451440405772200323040ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.util.Set; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.AbstractXMLStreamReader; import org.codehaus.jettison.Node; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.util.FastStack; public class MappedXMLStreamReader extends AbstractXMLStreamReader { private FastStack nodes; private String currentValue; private MappedNamespaceConvention convention; private String valueKey = "$"; private NamespaceContext ctx; private int popArrayNodes; public MappedXMLStreamReader(JSONObject obj) throws JSONException, XMLStreamException { this(obj, new MappedNamespaceConvention()); } public MappedXMLStreamReader(JSONObject obj, MappedNamespaceConvention con) throws JSONException, XMLStreamException { String rootName = (String) obj.keys().next(); this.convention = con; this.nodes = new FastStack(); this.ctx = con; Object top = obj.get(rootName); if (top instanceof JSONObject) { this.node = new Node(null, rootName, (JSONObject)top, convention); } else if (top instanceof JSONArray && !(((JSONArray)top).length() == 1 && ((JSONArray)top).get(0).equals(""))) { if (con.isRootElementArrayWrapper()) { this.node = new Node(null, rootName, obj, convention); } else { this.node = new Node(null, rootName, ((JSONArray)top).getJSONObject(0), convention); } } else { node = new Node(rootName, convention); convention.processAttributesAndNamespaces(node, obj); currentValue = JSONObject.NULL.equals(top) ? null : top.toString(); } nodes.push(node); event = START_DOCUMENT; } public int next() throws XMLStreamException { if (event == START_DOCUMENT) { event = START_ELEMENT; } else if (event == CHARACTERS) { event = END_ELEMENT; node = (Node) nodes.pop(); currentValue = null; } else if (event == START_ELEMENT || event == END_ELEMENT) { if (event == END_ELEMENT && nodes.size() > 0) { node = (Node) nodes.peek(); if (popArrayNodes > 0) { nodes.pop(); if (node.getArray() != null) { popArrayNodes--; event = END_ELEMENT; return event; } } } if (currentValue != null) { event = CHARACTERS; } else if ((node.getKeys() != null && node.getKeys().hasNext()) || node.getArray() != null) { processElement(); } else { if (nodes.size() > 0) { event = END_ELEMENT; node = (Node) nodes.pop(); } else { event = END_DOCUMENT; } } } // handle value in nodes with attributes if (nodes.size() > 0) { Node next = (Node)nodes.peek(); if (event == START_ELEMENT && next.getName().getLocalPart().equals(valueKey)) { event = CHARACTERS; node = (Node)nodes.pop(); } } return event; } private void processElement() throws XMLStreamException { try { Object newObj = null; String nextKey = null; if (node.getArray() != null) { int index = node.getArrayIndex(); if (index >= node.getArray().length()) { nodes.pop(); node = (Node) nodes.peek(); if (node == null) { event = END_DOCUMENT; return; } if ((node.getKeys() != null && node.getKeys().hasNext()) || node.getArray() != null) { if (popArrayNodes > 0) { node = (Node) nodes.pop(); } processElement(); } else { event = END_ELEMENT; node = (Node) nodes.pop(); } return; } newObj = node.getArray().get(index++); nextKey = node.getName().getLocalPart(); if (!"".equals(node.getName().getNamespaceURI())) { nextKey = this.convention.getPrefix(node.getName().getNamespaceURI()) + this.getConvention().getNamespaceSeparator() + nextKey; } node.setArrayIndex(index); } else { nextKey = (String) node.getKeys().next(); newObj = node.getObject().get(nextKey); } if (newObj instanceof String) { node = new Node(nextKey, convention); nodes.push(node); currentValue = (String) newObj; event = START_ELEMENT; return; } else if (newObj instanceof JSONArray) { JSONArray array = (JSONArray) newObj; if (!processUniformArrayIfPossible(nextKey, array)) { node = new Node(nextKey, convention); node.setArray(array); node.setArrayIndex(0); nodes.push(node); processElement(); } return; } else if (newObj instanceof JSONObject) { node = new Node((Node)nodes.peek(), nextKey, (JSONObject) newObj, convention); nodes.push(node); event = START_ELEMENT; return; } else { node = new Node(nextKey, convention); nodes.push(node); currentValue = JSONObject.NULL.equals(newObj) ? null : newObj.toString(); event = START_ELEMENT; return; } } catch (JSONException e) { throw new XMLStreamException(e); } } private boolean processUniformArrayIfPossible(String arrayKey, JSONArray array) throws JSONException, XMLStreamException { if (!isAvoidArraySpecificEvents(arrayKey)) { return false; } int arrayLength = array.length(); int depth = 0; String lastKey = null; int parentIndex = nodes.size(); boolean isRoot = ((Node)nodes.get(0)).getName().getLocalPart().equals(arrayKey); Node parent = !isRoot ? new Node(arrayKey, convention) : node; for (int i = arrayLength - 1; i >= 0; i--) { Object object = array.get(i); if (object instanceof JSONObject) { JSONObject jsonObject = (JSONObject)object; // lets limit to single key JSONObjects for now if (jsonObject.length() == 1) { String theKey = jsonObject.keys().next().toString(); if (lastKey == null || lastKey.equals(theKey)) { lastKey = theKey; depth++; Node theNode = new Node(parent, theKey, jsonObject, convention); nodes.push(theNode); } else { lastKey = null; break; } } } } if (lastKey == null) { for (int i = 0; i < depth; i++) { nodes.pop(); } return false; } parent.setArray(array); parent.setArrayIndex(arrayLength); if (!isRoot) { nodes.add(parentIndex, parent); nodes.push(parent); node = parent; event = START_ELEMENT; } else { node = (Node)nodes.pop(); processElement(); } popArrayNodes++; return true; } public void close() throws XMLStreamException { } public String getElementText() throws XMLStreamException { event = CHARACTERS; return currentValue; } public NamespaceContext getNamespaceContext() { return ctx; } public String getText() { if (currentValue != null && "null".equals(currentValue) && !convention.isReadNullAsString()) { return null; } return currentValue; } public void setValueKey(String valueKey) { this.valueKey = valueKey; } public boolean isAvoidArraySpecificEvents(String key) { Set keys = convention.getPrimitiveArrayKeys(); return keys != null && keys.contains(key); } public MappedNamespaceConvention getConvention() { return convention; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/MappedXMLStreamWriter.java000066400000000000000000000267241440405772200323630ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.IOException; import java.io.Writer; import java.util.Stack; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.AbstractXMLStreamWriter; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public class MappedXMLStreamWriter extends AbstractXMLStreamWriter { private static final String MIXED_CONTENT_VALUE_KEY = "$"; private MappedNamespaceConvention convention; protected Writer writer; private NamespaceContext namespaceContext; /** * What key is used for text content, when an element has both text and * other content? */ private String valueKey = MIXED_CONTENT_VALUE_KEY; /** Stack of open elements. */ private Stack stack = new Stack(); /** Element currently being processed. */ private JSONProperty current; /** * JSON property currently being constructed. For efficiency, this is * concretely represented as either a property with a String value or an * Object value. */ private abstract class JSONProperty { private String key; private String parentKey; public JSONProperty(String key, String parentKey) { this.key = key; this.parentKey = parentKey; } /** Get the key of the property. */ public String getKey() { return key; } public String getParentKey() { return parentKey; } public String getTreeKey() { return parentKey == null ? key : parentKey + "/" + key; } /** Get the value of the property */ public abstract Object getValue(); /** Add text */ public abstract void addText(String text); /** Return a new property object with this property added */ public abstract JSONPropertyObject withProperty(JSONProperty property, boolean add); public JSONPropertyObject withProperty(JSONProperty property) { return withProperty(property, true); } } /** * Property with a String value. */ private final class JSONPropertyString extends JSONProperty { private StringBuilder object = new StringBuilder(); public JSONPropertyString(String key, String parentKey) { super(key, parentKey); } public Object getValue() { return object.toString(); } public void addText(String text) { object.append(text); } public JSONPropertyObject withProperty(JSONProperty property, boolean add) { // Duplicate some code from JSONPropertyObject // because we can do things with fewer checks, and // therefore more efficiently. JSONObject jo = new JSONObject(false, convention.getIgnoredElements(), convention.isWriteNullAsString(), convention.isEscapeForwardSlashAlways()); try { // only add the text property if it's non-empty String strValue = getValue().toString(); if (MIXED_CONTENT_VALUE_KEY == valueKey) { strValue = strValue.trim(); } if (strValue.length() > 0) { jo.put(valueKey, strValue); } Object value = property.getValue(); boolean emptyString = value instanceof String && ((String)value).isEmpty(); if (value instanceof String && !emptyString) { value = convention.convertToJSONPrimitive((String)value); } if (getSerializedAsArrays().contains(getPropertyArrayKey(property))) { JSONArray values = new JSONArray(); if (!convention.isIgnoreEmptyArrayValues() || (!emptyString && value != null)) { values.put(value); } value = values; } jo.put(property.getKey(), value); } catch (JSONException e) { // Impossible by construction throw new AssertionError(e); } return new JSONPropertyObject(getKey(), getParentKey(), jo); } } /** * Property with a JSONObject value. */ private final class JSONPropertyObject extends JSONProperty { private JSONObject object; public JSONPropertyObject(String key, String parentKey, JSONObject object) { super(key, parentKey); this.object = object; } public Object getValue() { return object; } public void addText(String text) { if (MIXED_CONTENT_VALUE_KEY == valueKey) { text = text.trim(); if (text.length() == 0) { return; } } try { text = object.getString(valueKey) + text; } catch (JSONException e) { // no existing text, that's fine } try { if (valueKey != null) { object.put(valueKey, text); } } catch (JSONException e) { // Impossible by construction throw new AssertionError(e); } } public JSONPropertyObject withProperty(JSONProperty property, boolean add) { Object value = property.getValue(); if(value instanceof String && !((String)value).isEmpty()) { value = convention.convertToJSONPrimitive((String)value); } Object old = object.opt(property.getKey()); try { if(old != null) { JSONArray values; // Convert an existing property to an array // and append to the array if (old instanceof JSONArray) { values = (JSONArray)old; } else { values = new JSONArray(); values.put(old); } values.put(value); object.put(property.getKey(), values); } else if(getSerializedAsArrays().contains(getPropertyArrayKey(property))) { JSONArray values = new JSONArray(); boolean emptyString = value instanceof String && ((String)value).isEmpty(); if (!convention.isIgnoreEmptyArrayValues() || (!emptyString && value != null)) { values.put(value); } object.put(property.getKey(), values); } else { // Add the property directly. object.put(property.getKey(), value); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return this; } } public MappedXMLStreamWriter(MappedNamespaceConvention convention, Writer writer) { super(); this.convention = convention; this.writer = writer; this.namespaceContext = convention; } private String getPropertyArrayKey(JSONProperty property) { return isArrayKeysWithSlashAvailable() ? property.getTreeKey() : property.getKey(); } public NamespaceContext getNamespaceContext() { return namespaceContext; } public void setNamespaceContext(NamespaceContext context) throws XMLStreamException { this.namespaceContext = context; } public String getTextKey() { return valueKey; } public void setValueKey(String valueKey) { this.valueKey = valueKey; } public void writeStartDocument() throws XMLStreamException { // The document is an object with one property -- the root element current = new JSONPropertyObject(null, null, new JSONObject(convention.isDropRootElement(), convention.getIgnoredElements(), convention.isWriteNullAsString(), convention.isEscapeForwardSlashAlways())); stack.clear(); } public void writeStartElement(String prefix, String local, String ns) throws XMLStreamException { if (current == null) { this.writeStartDocument(); } String parentKey = current.getTreeKey(); stack.push(current); String key = convention.createKey(prefix, ns, local); current = new JSONPropertyString(key, parentKey); } public void writeAttribute(String prefix, String ns, String local, String value) throws XMLStreamException { String key = convention.isElement(prefix, ns, local) ? convention.createKey(prefix, ns, local) : convention.createAttributeKey(prefix, ns, local); JSONPropertyString prop = new JSONPropertyString(key, null); prop.addText(value); current = current.withProperty(prop, false); } public void writeAttribute(String ns, String local, String value) throws XMLStreamException { writeAttribute(null, ns, local, value); } public void writeAttribute(String local, String value) throws XMLStreamException { writeAttribute(null, local, value); } public void writeCharacters(String text) throws XMLStreamException { current.addText(text); } public void writeEndElement() throws XMLStreamException { if (stack.isEmpty()) throw new XMLStreamException("Too many closing tags."); current = stack.pop().withProperty(current); } public void writeEndDocument() throws XMLStreamException { if (!stack.isEmpty()) throw new XMLStreamException("Missing some closing tags."); // We know the root is a JSONPropertyObject so this cast is safe writeJSONObject((JSONObject)current.getValue()); try { writer.flush(); } catch (IOException e) { throw new XMLStreamException(e); } } /** * For clients who want to modify the output object before writing to override. * @param root root * @throws XMLStreamException XMLStreamException */ protected void writeJSONObject(JSONObject root) throws XMLStreamException { try { if (root == null) writer.write("null"); else root.write(writer); } catch (JSONException e) { throw new XMLStreamException(e); } catch (IOException e) { throw new XMLStreamException(e); } } ////////////////////////////////////////////////////////////////////////////////////////// // The following methods are supplied only to satisfy the interface public void close() throws XMLStreamException { // TODO Auto-generated method stub } public void flush() throws XMLStreamException { // TODO Auto-generated method stub } public String getPrefix(String arg0) throws XMLStreamException { // TODO Auto-generated method stub return null; } public Object getProperty(String arg0) throws IllegalArgumentException { // TODO Auto-generated method stub return null; } public void setDefaultNamespace(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void setPrefix(String arg0, String arg1) throws XMLStreamException { // TODO Auto-generated method stub } public void writeDefaultNamespace(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void writeEntityRef(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void writeNamespace(String arg0, String arg1) throws XMLStreamException { // TODO Auto-generated method stub } public void writeProcessingInstruction(String arg0) throws XMLStreamException { // TODO Auto-generated method stub } public void writeProcessingInstruction(String arg0, String arg1) throws XMLStreamException { // TODO Auto-generated method stub } public MappedNamespaceConvention getConvention() { return convention; } }jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/SimpleConverter.java000066400000000000000000000016431440405772200313350ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; /** * Simple converter that treats everything as strings * * @author Dejan Bosanac * @since 1.1 */ public class SimpleConverter implements TypeConverter { public Object convertToJSONPrimitive(String text) { return text; } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/mapped/TypeConverter.java000066400000000000000000000015411440405772200310220ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; /** * Supports customized type conversion * * @author Dejan Bosanac * @since 1.1 */ public interface TypeConverter { public Object convertToJSONPrimitive(String text); } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/util/000077500000000000000000000000001440405772200250545ustar00rootroot00000000000000jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/util/FastStack.java000066400000000000000000000021651440405772200276060ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.util; import java.util.ArrayList; import java.util.EmptyStackException; public class FastStack extends ArrayList { public void push(Object o) { add(o); } public Object pop() { if (empty()) throw new EmptyStackException(); return remove(size() - 1); } public boolean empty() { return size() == 0; } public Object peek() { if (empty()) throw new EmptyStackException(); return get(size() - 1); } } jettison-jettison-1.5.4/src/main/java/org/codehaus/jettison/util/StringIndenter.java000066400000000000000000000234251440405772200306640ustar00rootroot00000000000000/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.util; /** *

 * indent json, assumes the input is not yet indented.  here is an example:
 * {
 * "FastResponseJs":{
 *   "ajaxElements":{
 *     "AjaxMapEntry":[
 *       {
 *         "theKey":{
 *           "@class":"string",
 *           "$":"ajax1a"
 *         },
 *         "theValue":{
 *           "@class":"AjaxEvent",
 *           "ajaxSendFormNames":{
 *             "string":"ajax1"
 *           },
 *           "ajaxEventType":"NORMAL",
 *           "eventName":"onblur",
 *           "ajaxId":"PRLZY5QZ",
 *           "screenElementId":"ajax1a",
 *           "asynchronous":true,
 *           "disableValidation":true
 *         }
 *         
 *       },
 *       {
 *         "theKey":{
 *        ...
 *        
 *        
 *   Usage: String formatted = new StringIndenter(jsonString).result();
 * 
*/ public class StringIndenter { /** chars to process */ private String json; /** current start tag */ private int startTagIndex; /** current end tag */ private int endTagIndex; /** current number of indents (times to is the indent */ private int currentNumberOfIndents; /** result */ private StringBuilder result; /** * get the result * @return the result */ public String result() { try { this.indent(); } catch (RuntimeException re) { throw new RuntimeException("Problem here: " + this, re); } if (this.json == null) { return null; } String resultString = this.result.toString(); return resultString.trim(); } /** * indent the string */ private void indent() { if (this.json == null) { return; } this.result = new StringBuilder(); this.startTagIndex = -1; this.endTagIndex = -1; this.currentNumberOfIndents = 0; //{ // "a":{ // "b\"b":{ // "c\\":"d" // }, // "e":"f", // "g":[ // "h":"i" // ] // } //} while(true) { this.startTagIndex = findStartTagIndex(); if (this.startTagIndex == -1) { //cant find anything else... make sure everything there if (this.endTagIndex != this.json.length()-1) { this.result.append(this.json, this.endTagIndex+1, this.json.length()); } break; } //handles first tag if (instantIndent(this.json, this.startTagIndex)) { this.currentNumberOfIndents++; this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } //handles end of associative array with comma if (instantUnindentTwoChars(this.json, this.startTagIndex)) { this.currentNumberOfIndents--; //this is on a line by itself this.newlineIndent(); this.printNewlineIndent(this.startTagIndex, this.startTagIndex+2); this.endTagIndex = this.startTagIndex+1; continue; } //handles end of array with comma if (instantUnindent(this.json, this.startTagIndex)) { this.currentNumberOfIndents--; if (onNewline()) { this.unindent(); } else { this.newlineIndent(); } this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } //handles end of array with comma if (instantNewline(this.json, this.startTagIndex)) { this.printNewlineIndent(this.startTagIndex, this.startTagIndex+1); this.endTagIndex = this.startTagIndex; continue; } this.endTagIndex = findEndTagIndex(); //one thing's for sure, we are printing out this tag this.result.append(this.json, this.startTagIndex, this.endTagIndex+1); //go back to top to end if (this.endTagIndex >= this.json.length()-1) { continue; } char nextChar = this.json.charAt(this.endTagIndex+1); //if next is colon, print that out too if (nextChar == ':') { this.result.append(':'); this.endTagIndex++; } //ready to loop around... } } /** * see if current pos is on newline * @return true if on new line */ private boolean onNewline() { for (int i=this.result.length()-1;i>=0;i--) { char curChar = this.result.charAt(i); if (curChar == '\n') { return true; } if (Character.isWhitespace(curChar)) { continue; } //if not whitespace, then not on own line return false; } //i guess first line is new line return true; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantIndent(String json, int index) { char curChar = json.charAt(index); if (curChar == '{' || curChar == '[') { return true; } return false; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantNewline(String json, int index) { char curChar = json.charAt(index); if (curChar == ',') { return true; } return false; } /** * see if instant unindent * @param json * @param index * @return if it is an instant unindent */ private static boolean instantUnindent(String json, int index) { char curChar = json.charAt(index); if (curChar == '}' || curChar == ']') { return true; } return false; } /** * see if instant indent * @param json * @param index * @return if it is an instant indent */ private static boolean instantUnindentTwoChars(String json, int index) { char curChar = json.charAt(index); if (index == json.length()-1) { return false; } char nextchar = json.charAt(index+1); if (curChar == '}' && nextchar == ',') { return true; } return false; } /** * put a newline and indent * @param start * @param end */ private void printNewlineIndent(int start, int end) { //lets put this tag on the queue this.result.append(this.json, start, end); this.newlineIndent(); } /** * put a newline and indent */ private void newlineIndent() { this.result.append("\n").append(repeat(" ", this.currentNumberOfIndents)); } /** * repeat a string a certain number of times. * @param theString * @param times * @return the string */ private static String repeat(String theString, int times) { StringBuilder result = new StringBuilder(); //loop through, keep appending for (int i = 0; i < times; i++) { result.append(theString); } return result.toString(); } /** * unindent a previous indent if it is there */ private void unindent() { for (int i=0;i<2;i++) { if (this.result.charAt(this.result.length()-1) == ' ') { this.result.deleteCharAt(this.result.length()-1); } } } /** * after the last end tag, find the next start tag * @return the next start tag */ private int findStartTagIndex() { return findNextStartTagIndex(this.json, this.endTagIndex+1); } /** * after the last start tag, find the next end start tag * @return the next start tag */ private int findEndTagIndex() { return findNextEndTagIndex(this.json, this.startTagIndex+1); } /** * find the start tag from json and a start from index * either look for a quote, {, [ or scalar. generally not whitespace * @param json * @param startFrom * @return the start tag index of -1 if not found another */ private static int findNextStartTagIndex(String json, int startFrom) { int length = json.length(); for (int i= startFrom; iDejan Bosanac * @author twayne * @since 21-Mar-2008 */ public class BadgerFishDOMTest extends DOMTest { public BadgerFishDOMTest() throws Exception { super(); } public void testSimple() throws Exception { String xmlStr = "the frog"; String expStr = "{\"kermit\":{\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testSimpleAttribute() throws Exception { String xmlStr = "the frog"; String expStr = "{\"kermit\":{\"@mygirl\":\"piggy\",\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testDefaultNamespace() throws Exception { String xmlStr = "the frog"; String expStr = "{\"kermit\":{\"@xmlns\":{\"$\":\"http:\\/\\/somens\"},\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testElementNamespace() throws Exception { String xmlStr = "the frog"; String expStr = "{\"ns1:kermit\":{\"@xmlns\":{\"ns1\":\"http:\\/\\/somens\"},\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testElementAttributeNamespace() throws Exception { String xmlStr = "the frog"; String expStr = "{\"ns1:kermit\":{\"@xmlns\":{\"ns1\":\"http:\\/\\/somens\"},\"@ns1:mygirl\":\"piggy\",\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testParentScopedElementNamespace() throws Exception { String xmlStr = "10"; String expStr = "{\"ns:A\":{\"@xmlns\":{\"ns\":\"http:\\/\\/json\\/test\"},\"ns:B\":{\"ns:C\":{\"ns:D\":{\"ns:E\":{\"$\":\"10\"}}}}}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr).replace(System.getProperty("line.separator"), "").replaceAll(">\\s+<", "><"); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testParentScopedAttributeNamespace() throws Exception { String xmlStr = "

30

"; String expStr = "{\"P\":{\"@xmlns\":{\"$\":\"http:\\/\\/json\\/test\"},\"Q\":{\"R\":{\"@xmlns\":{\"ns\":\"http:\\/\\/foo\"},\"S\":{\"@ns:a\":\"bar\",\"T\":{\"$\":\"30\"}}}}}}"; String resStr = toJSON(parse(xmlStr)); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr).replace(System.getProperty("line.separator"), "").replaceAll(">\\s+<", "><"); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } private String toJSON(Element srcDOM) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); new BadgerFishDOMDocumentSerializer(baos).serialize(srcDOM); return new String(baos.toByteArray()); } private String toXML(String jsonStr) throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(jsonStr.getBytes()); Document resDOM = new BadgerFishDOMDocumentParser().parse(bais); return printNode(resDOM); } } BadgerFishXMLInputFactoryTest.java000066400000000000000000000025341440405772200346070ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.io.StringReader; import javax.xml.stream.XMLStreamReader; import junit.framework.TestCase; public class BadgerFishXMLInputFactoryTest extends TestCase { private static final String XML_JSON = "{\"d:root\":{\"child\":{\"@xsi:type\":\"d:ChildType\",\"name\":{\"$\":\"Dummy\"}},\"@xmlns\":{\"d\":\"http:\\/\\/www.example.com\\/dummy\",\"xsi\":\"http:\\/\\/www.w3.org\\/2001\\/XMLSchema-instance\"}}}"; public void testRoundTrip() throws Exception { BadgerFishXMLInputFactory xif = new BadgerFishXMLInputFactory(); XMLStreamReader reader = xif.createXMLStreamReader(new StringReader(XML_JSON)); while (reader.hasNext()) { reader.next(); } } } BadgerFishXMLStreamReaderTest.java000066400000000000000000000267041440405772200345430ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import junit.framework.TestCase; import org.codehaus.jettison.AbstractXMLStreamReader; import org.codehaus.jettison.badgerfish.BadgerFishXMLStreamReader; import org.codehaus.jettison.json.JSONObject; public class BadgerFishXMLStreamReaderTest extends TestCase { public void testRootWithText() throws Exception { JSONObject obj = new JSONObject("{ \"alice\": { \"$\" : \"bob\" } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(-1, reader.getLocation().getLineNumber()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("bob", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_DOCUMENT, reader.next()); } public void testTwoChildren() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\": { \"bob\" : { \"$\": \"charlie\" }," + " \"david\": { \"$\": \"edgar\"} } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("charlie", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("david", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("edgar", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("david", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testTwoChildrenWithSameName() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\": { \"bob\" : [ {\"$\": \"charlie\" }, {\"$\": \"david\" } ] } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("charlie", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("david", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testAttributeAndText() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\": { \"$\" : \"bob\", \"@charlie\" : \"david\" } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("bob", reader.getText()); assertEquals(1, reader.getAttributeCount()); assertEquals("charlie", reader.getAttributeLocalName(0)); assertEquals("david", reader.getAttributeValue(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testDefaultNamespace() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\": { \"$\" : \"bob\", \"@xmlns\": { \"$\" : \"http:\\/\\/some-namespace\"} } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("bob", reader.getText()); assertEquals(0, reader.getAttributeCount()); assertEquals(1, reader.getNamespaceCount()); assertEquals("http://some-namespace", reader.getNamespaceURI(0)); assertEquals("", reader.getNamespacePrefix(0)); assertEquals("http://some-namespace", reader.getNamespaceURI("")); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testPrefixedNamespace() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\": { \"$\" : \"bob\", \"@xmlns\": { \"$\" : \"http:\\/\\/some-namespace\", \"charlie\" : \"http:\\/\\/some-other-namespace\" } } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("bob", reader.getText()); assertEquals(0, reader.getAttributeCount()); assertEquals(2, reader.getNamespaceCount()); // namespaces are ordered differently on different platforms/jvms, // so we can't really test the order // assertEquals("http://some-namespace", reader.getNamespaceURI(0)); // assertEquals("", reader.getNamespacePrefix(0)); assertEquals("http://some-namespace", reader.getNamespaceURI("")); // assertEquals("http://some-other-namespace", reader.getNamespaceURI(1)); // assertEquals("charlie", reader.getNamespacePrefix(1)); assertEquals("http://some-other-namespace", reader.getNamespaceURI("charlie")); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testPrefixedElements() throws Exception { JSONObject obj = new JSONObject( "{ \"alice\" : { " + "\"bob\" : { " + "\"$\" : \"david\" , " + "\"@xmlns\" : {" + "\"charlie\" : \"http:\\/\\/some-other-namespace\" , " + "\"$\" : \"http:\\/\\/some-namespace\"} " + "} , " + "\"charlie:edgar\" : { " + "\"$\" : \"frank\" , " + "\"@xmlns\" : {" + "\"charlie\":\"http:\\/\\/some-other-namespace\", " + "\"$\" : \"http:\\/\\/some-namespace\"" + "} " + "}, " + "\"@xmlns\" : { " + "\"charlie\" : \"http:\\/\\/some-other-namespace\", " + "\"$\" : \"http:\\/\\/some-namespace\"" + "} " + "} }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("bob", reader.getLocalName()); assertEquals(0, reader.getAttributeCount()); assertEquals(2, reader.getNamespaceCount()); // assertEquals("http://some-namespace", reader.getNamespaceURI(0)); // assertEquals("", reader.getNamespacePrefix(0)); assertEquals("http://some-namespace", reader.getNamespaceURI("")); // assertEquals("http://some-other-namespace", reader.getNamespaceURI(1)); // assertEquals("charlie", reader.getNamespacePrefix(1)); assertEquals("http://some-other-namespace", reader.getNamespaceURI("charlie")); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("david", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("bob", reader.getName().getLocalPart()); // ---- assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("edgar", reader.getLocalName()); assertEquals("charlie", reader.getPrefix()); assertEquals("http://some-other-namespace", reader.getNamespaceURI()); assertEquals(0, reader.getAttributeCount()); assertEquals(2, reader.getNamespaceCount()); // assertEquals("http://some-namespace", reader.getNamespaceURI(0)); // assertEquals("", reader.getNamespacePrefix(0)); assertEquals("http://some-namespace", reader.getNamespaceURI("")); // assertEquals("http://some-other-namespace", reader.getNamespaceURI(1)); // assertEquals("charlie", reader.getNamespacePrefix(1)); assertEquals("http://some-other-namespace", reader.getNamespaceURI("charlie")); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("frank", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("edgar", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); } public void testElementWithInvalidValue() throws Exception { JSONObject obj = new JSONObject("{ \"alice\": { \"foo\" : \"bob\" } }"); AbstractXMLStreamReader reader = new BadgerFishXMLStreamReader(obj); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("alice", reader.getName().getLocalPart()); try { reader.next(); fail("Must cause exception"); } catch (XMLStreamException e) { } } } BadgerFishXMLStreamWriterTest.java000066400000000000000000000223211440405772200346040ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/badgerfish/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.badgerfish; import java.io.StringWriter; import junit.framework.TestCase; import org.codehaus.jettison.AbstractXMLStreamWriter; import org.codehaus.jettison.badgerfish.BadgerFishXMLStreamWriter; public class BadgerFishXMLStreamWriterTest extends TestCase { public void testRootWithText() throws Exception { StringWriter strWriter = new StringWriter(); AbstractXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeCharacters("bob"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{\"alice\":{\"$\":\"bob\"}}", strWriter.toString()); } private void assertJSONEquals(String string, String string2) { string = string.replace(" ", ""); string2 = string2.replace(" ", ""); assertEquals(string, string2); } public void testTwoChildren() throws Exception { StringWriter strWriter = new StringWriter(); AbstractXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeStartElement("bob"); w.writeCharacters("charlie"); w.writeEndElement(); w.writeStartElement("david"); w.writeCharacters("edgar"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{\"alice\":{\"bob\":{\"$\":\"charlie\"},"+ "\"david\":{\"$\":\"edgar\"}}}", strWriter.toString()); } public void testTwoChildrenWithSameName() throws Exception { StringWriter strWriter = new StringWriter(); AbstractXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeStartElement("bob"); w.writeCharacters("charlie"); w.writeEndElement(); w.writeStartElement("bob"); w.writeCharacters("david"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{\"alice\":{\"bob\":[{\"$\":\"charlie\"},{\"$\":\"david\"}]}}", strWriter.toString()); } public void testMultipleChildrenAgain() throws Exception { StringWriter strWriter = new StringWriter(); AbstractXMLStreamWriter xsw = new BadgerFishXMLStreamWriter(strWriter); xsw.writeStartDocument(); xsw.writeStartElement("Ratings"); xsw.writeStartElement("Rating"); xsw.writeAttribute("id", "100"); xsw.writeAttribute("value", "3"); xsw.writeEndElement(); xsw.writeStartElement("Rating"); xsw.writeAttribute("id", "200"); xsw.writeAttribute("value", "4"); xsw.writeEndElement(); xsw.writeStartElement("Rating"); xsw.writeAttribute("id", "300"); xsw.writeAttribute("value", "5"); xsw.writeEndElement(); xsw.writeEndElement(); xsw.writeEndDocument (); xsw.flush(); xsw.close(); strWriter.close(); System.out.println(strWriter.toString()); assertJSONEquals("{\"Ratings\":{\"Rating\":[" + "{\"@id\":\"100\",\"@value\":\"3\"}," + "{\"@id\":\"200\",\"@value\":\"4\"}," + "{\"@id\":\"300\",\"@value\":\"5\"}" + "]}}", strWriter.toString()); } public void testAttributeAndText() throws Exception { StringWriter strWriter = new StringWriter(); AbstractXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeAttribute("charlie", "david"); w.writeCharacters("bob"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{\"alice\":{\"@charlie\":\"david\",\"$\":\"bob\"}}", strWriter.toString()); } public void testDefaultNamespace() throws Exception { StringWriter strWriter = new StringWriter(); BadgerFishXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeDefaultNamespace("http://some-namespace"); w.writeCharacters("bob"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{\"alice\":{\"@xmlns\":{\"$\":\"http:\\/\\/some-namespace\"},\"$\":\"bob\"}}", strWriter.toString()); } public void testPrefixedNamespace() throws Exception { StringWriter strWriter = new StringWriter(); BadgerFishXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeDefaultNamespace("http://some-namespace"); w.writeNamespace("charlie", "http://some-other-namespace"); assertEquals("http://some-other-namespace", w.getNamespaceContext().getNamespaceURI("charlie")); assertEquals("charlie", w.getNamespaceContext().getPrefix("http://some-other-namespace")); w.writeCharacters("bob"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals("{ \"alice\": { \"@xmlns\": { \"$\" : \"http:\\/\\/some-namespace\", \"charlie\" : \"http:\\/\\/some-other-namespace\" }, \"$\" : \"bob\" } }", strWriter.toString()); } public void testPrefixedElements() throws Exception { StringWriter strWriter = new StringWriter(); BadgerFishXMLStreamWriter w = new BadgerFishXMLStreamWriter(strWriter); w.writeStartDocument(); w.writeStartElement("alice"); w.writeDefaultNamespace("http://some-namespace"); w.writeNamespace("charlie", "http://some-other-namespace"); w.writeStartElement("bob"); w.writeCharacters("david"); w.writeEndElement(); w.writeStartElement("charlie", "edgar", "http://some-other-namespace"); w.writeCharacters("frank"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertJSONEquals( "{ \"alice\" : { " + "\"@xmlns\" : { " + "\"$\" : \"http:\\/\\/some-namespace\"," + "\"charlie\" : \"http:\\/\\/some-other-namespace\"" + "}, " + "\"bob\" : { " + "\"$\" : \"david\" " + "}, " + "\"charlie:edgar\" : { " + "\"$\" : \"frank\" " + "} " + "} }", strWriter.toString()); } /** * * charlieedgar * * charliedavid * { \"alice\": { \"bob\" : [{\"$\": charlie\" }, {\"$\": \"david\" }] } } * * bob * { \"alice\": { \"$\" : \"bob\", \"@charlie\" : \"david\" } } * * bob * { \"alice\": { \"$\" : \"bob\", \"@xmlns\": { \"$\" : \"http:\/\/some-namespace\"} } } * * bob * { \"alice\": { \"$\" : \"bob\", \"@xmlns\": { \"$\" : \"http:\/\/some-namespace\", \"charlie\" : \"http:\/\/some-other-namespace\" } } } * * david frank * { \"alice\" : { \"bob\" : { \"$\" : \"david\" , \"@xmlns\" : {\"charlie\" : \"http:\/\/some-other-namespace\" , \"$\" : \"http:\/\/some-namespace\"} } , \"charlie:edgar\" : { \"$\" : \"frank\" , \"@xmlns\" : {\"charlie\":\"http:\/\/some-other-namespace\", \"$\" : \"http:\/\/some-namespace\"} }, \"@xmlns\" : { \"charlie\" : \"http:\/\/some-other-namespace\", \"$\" : \"http:\/\/some-namespace\"} } } * * @throws Exception */ } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/badgerfish/RoundTripTest.java000077500000000000000000001111261440405772200316660ustar00rootroot00000000000000package org.codehaus.jettison.badgerfish; import java.awt.Color; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.net.URI; import java.util.HashSet; import java.util.Iterator; import java.util.Random; import java.util.Set; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import junit.framework.TestCase; /** * Test large scale object round trips. */ public class RoundTripTest extends TestCase { // ======================================================================== // JUnit Tests // ======================================================================== public void testEqualsHashCode() { DataSet ds1, ds2, ds3; ds1 = new DataSet(); ds2 = new DataSet(); ds3 = new DataSet(); // test null.. try { ds3.setDataPoints(null); fail("Suppose to throw null pointer exception.."); } catch (NullPointerException npe) { // success } // test null.. try { ds3.addDataPoint(null); fail("Suppose to throw null pointer exception.."); } catch (NullPointerException npe) { // success } // standard checks.. assertTrue(ds1.equals(ds1)); assertFalse(ds1.equals(null)); assertFalse(ds1.equals(new Object())); // setup the name of the data set.. ds1.setName("Some name"); ds2.setName("Some name"); // add random data points.. addRandomDataPoints(15, ds1, ds2); addRandomDataPoints(15, ds3); assertTrue(ds1.equals(ds2)); assertFalse(ds1.equals(ds3)); Set set = new HashSet(); set.add(ds1); set.add(ds2); set.add(ds3); assertTrue(set.size() == 2); } public void testSerializeDeserialize() throws Exception { DataSet ds = new DataSet(); ds.setName("Some Name!"); // addRandomDataPoints(50, ds); addRandomDataPoints(90, ds); assertRoundTrip(ds, new DataSet()); } // ======================================================================== // Helper Methods // ======================================================================== public File serialize(File f, XMLStreamObject t) throws Exception { XMLStreamWriter xwrt = new BadgerFishXMLOutputFactory().createXMLStreamWriter(new FileWriter(f)); xwrt.writeStartDocument(); t.toXMLStream(xwrt); xwrt.writeEndDocument(); xwrt.flush(); xwrt.close(); return f; } public XMLStreamObject deserialize(File f, XMLStreamObject t) throws Exception { XMLStreamReader xrdr = new BadgerFishXMLInputFactory().createXMLStreamReader(new FileReader(f)); t.fromXMLStream(xrdr); return t; } public void assertRoundTrip(XMLStreamObject instance, XMLStreamObject newInstance) throws Exception { File f = File.createTempFile("json", ".txt"); try { serialize(f, instance); XMLStreamObject t = deserialize(f, newInstance); assertEquals(instance, t); } finally { f.delete(); } } /** * Adds the number of random data points to the data set. * * @param size * @param ds */ void addRandomDataPoints(int size, DataSet ds) { addRandomDataPoints(size, ds, null); } /** * Adds the number of random data point to both data sets. */ void addRandomDataPoints(int size, DataSet d1, DataSet d2) { Random rnd = new Random(System.currentTimeMillis()); for (int i = 0; i < size; i++) { String label = "Label--" + i; Number value = new Double(rnd.nextDouble()); d1.addDataPoint(new DataPoint(label, value)); if (d2 != null) { d2.addDataPoint(new DataPoint(label, value)); } } } /** * Simple model class to represent a data point in the chart. */ public static class DataPoint implements XMLStreamObject { // ======================================================================= // Fields // ======================================================================= URI uri; Color color; String label; Number value; // ======================================================================= // Constructors // ======================================================================= /** * Default constructor. */ public DataPoint() { } /** * When only a value exists. */ public DataPoint(Number value) { this(null, null, value, null); } /** * When only a label and value exist for the data point. */ public DataPoint(String label, Number value) { this(null, label, value, null); } /** * When only a label, value, and color exist for the data point. */ public DataPoint(String label, Number value, Color color) { this(null, label, value, color); } /** * Simple constructor to set all properties. * * @param uri used for image maps. * @param label used to label each point. * @param value used as the range value for the point. * @param color used to change the color of the point. */ public DataPoint(URI uri, String label, Number value, Color color) { if (uri != null) { setURI(uri); } setColor(color); setLabel(label); setValue(value); } // ======================================================================= // Color Property // ======================================================================= /** * Color of the data point. This could be a pie slice or a bar in a * chart. */ public Color getColor() { return color; } /** * Value can be null to signify default value. Otherwise must be a * color. */ public void setColor(Color color) { this.color = color; } /** * Sets the color of the data point based on the string received. * * @throws NumberFormatException if the string does not conform to a * number color string. * @throws NullPointerException if the string is null. * @param color */ public void setColor(String color) { this.color = Color.decode(color); } // ======================================================================= // Label Property // ======================================================================= /** * Label for the slice or bar. */ public String getLabel() { return label; } /** * Sets the label. Blank input will result in a 'null' value. */ public void setLabel(String label) { this.label = (StringUtil.isBlank(label)) ? null : label; } // ======================================================================= // Value Property // ======================================================================= /** * Actual value of the bar or slice. */ public Number getValue() { return value; } /** * Sets the range value for this data point. * * @throws NullPointerException if the parameter provided is null. * @param value Any number preferably a Double. */ public void setValue(Number value) { if (value == null) { NullPointerException npe = new NullPointerException(); throw npe; } this.value = value; } /** * Set the value based on the string. A Double is used for the basis. * * @throws NumberFormatException if value is not a valid number. * @see java.lang.Double */ void setValue(String value) { // use double since it has a fairly large range this.value = Double.valueOf(value); } // ======================================================================= // URI Property // ======================================================================= /** * Links for image maps etc.. */ public URI getURI() { return this.uri; } /** * Sets the URI for the data point. * * @throws NullPointerException if value is null. */ public void setURI(URI value) { if (value == null) { NullPointerException npe = new NullPointerException(); throw npe; } this.uri = value; } /** * Sets a URI for a image map parameter. * * @throws IllegalArgumentException - If the given string violates RFC * 2396 or is blank. */ public void setURI(String value) { final String ERROR = "Invalid URI value!"; if (StringUtil.isBlank(value)) { throw new IllegalArgumentException(ERROR); } this.uri = java.net.URI.create(value); } // ======================================================================= // Object Overrides // ======================================================================= /** * Determine if the object is equal. */ public boolean equals(Object obj) { if (obj == null || !(obj instanceof DataPoint)) { return false; } if (this == obj) { return true; } DataPoint dp = (DataPoint)obj; EqualsBuilder bld = new EqualsBuilder(); bld.append(getColor(), dp.getColor()); bld.append(getLabel(), dp.getLabel()); bld.append(getValue(), dp.getValue()); bld.append(getURI(), dp.getURI()); return bld.isEquals(); } /** * Must implement hashCode if implementing equals. */ public int hashCode() { HashCodeBuilder bld = new HashCodeBuilder(); bld.append(getColor()); bld.append(getLabel()); bld.append(getValue()); bld.append(getURI()); return bld.toHashCode(); } // ======================================================================= // XML // ======================================================================= static final String ELEMENT = "DataPoint"; static final String VALUE = "value"; static final String COLOR = "color"; static final String LABEL = "label"; static final String URI = "uri"; /** * Value is represented by a Double on parsing. * * @see com.sun.idm.xml.XMLStreamObject#fromXMLStream(javax.xml.stream.XMLStreamReader) */ public void fromXMLStream(XMLStreamReader xrdr) throws XMLStreamException { // clear out all variables that may not be there.. uri = null; label = null; color = null; do { int tag = xrdr.getEventType(); if (XMLStreamReader.START_ELEMENT == tag && ELEMENT.equals(xrdr.getLocalName())) { int count = xrdr.getAttributeCount(); for (int x = 0; x < count; x++) { String name = xrdr.getAttributeLocalName(x); String value = xrdr.getAttributeValue(x); if (VALUE.equals(name)) { setValue(value); } else if (LABEL.equals(name)) { setLabel(value); } else if (COLOR.equals(name)) { setColor(value); } else if (URI.equals(name)) { setURI(value); } } // found it so we're done here.. break; } } while (xrdr.next() != XMLStreamReader.END_DOCUMENT); } /* * (non-Javadoc) * * @see com.sun.idm.xml.XMLStreamObject#toXMLStream(javax.xml.stream.XMLStreamWriter) */ public void toXMLStream(XMLStreamWriter xwrt) throws XMLStreamException { xwrt.writeStartElement(ELEMENT); if (getColor() != null) { String color = ColorUtil.colorToString(getColor()); xwrt.writeAttribute(COLOR, color); } if (StringUtil.isNotBlank(getLabel())) { xwrt.writeAttribute(LABEL, getLabel()); } if (getURI() != null) { xwrt.writeAttribute(URI, getURI().toString()); } xwrt.writeAttribute(VALUE, getValue().toString()); xwrt.writeEndElement(); } } /** * Simple interface that should the object supports streaming XML data * in/out. */ public interface XMLStreamObject { /** * Writes the object to the stream. This stream writer has support for * various formats including XML, FastInfoSet and JSON. * * @param wrt Writer for streaming the content through. * @throws XMLStreamException */ public void toXMLStream(XMLStreamWriter wrt) throws XMLStreamException; /** * Reads the object from the stream this is an example of pull parsing. * It can be used on various formats a well. Formats include XML, * FastInfo Set, and JSON. * * @param rdr Reader for streaming the content through. * @throws XMLStreamException if the content is cut off or malformed. */ public void fromXMLStream(XMLStreamReader rdr) throws XMLStreamException; } /** * Simple model to represent a chart's data set. */ public class DataSet implements XMLStreamObject { /** * Name of the data set or category depending on the translation. */ String name; /** * Use a 'Set' to avoid any duplicates. */ Set dataPoints; /** * Empty constructor for just using the set methods. */ public DataSet() { // set the defaults.. this(null, new HashSet()); } /** * Set the name and data points for the data set. */ public DataSet(String name, Set dataPoints) { setName(name); setDataPoints(dataPoints); } /** * Get the group of data points. */ public Set getDataPoints() { return dataPoints; } /** * Set the group of data points. Using a set to avoid duplicates. * * @throws NullPointerException if value is null. */ public void setDataPoints(Set value) { if (value == null) { throw new NullPointerException(); } this.dataPoints = value; } /** * Add a data point to the set of data points.. * * @throws NullPointerException if value is null. */ public void addDataPoint(DataPoint value) { if (value == null) { throw new NullPointerException(); } this.dataPoints.add(value); } /** * Get the name/category of the data set. */ public String getName() { return name; } /** * Set the name of the data set. */ public void setName(String value) { this.name = StringUtil.isBlank(value) ? null : value; } /** * Determine if two objects values are equal. */ public boolean equals(Object obj) { if (obj == null || !(obj instanceof DataSet)) { return false; } if (obj == this) { return true; } DataSet ds = (DataSet)obj; EqualsBuilder bld = new EqualsBuilder(); bld.append(getName(), ds.getName()); bld.append(getDataPoints(), ds.getDataPoints()); return bld.isEquals(); } /** * Must override hashCode if using equals. */ public int hashCode() { HashCodeBuilder bld = new HashCodeBuilder(); bld.append(getName()); bld.append(getDataPoints()); return bld.toHashCode(); } // ======================================================================= // XMLStreamObject Interface // ======================================================================= static final String ELEMENT = "dataset"; private static final String NAME = "name"; /* * (non-Javadoc) * * @see com.sun.idm.xml.XMLStreamObject#fromXMLStream(javax.xml.stream.XMLStreamReader) */ public void fromXMLStream(XMLStreamReader xrdr) throws XMLStreamException { // clear the current data.. name = null; dataPoints.clear(); // optimization.. boolean found = false; do { int tag = xrdr.getEventType(); if (XMLStreamReader.START_ELEMENT == tag) { String name = xrdr.getLocalName(); // find the start element if (!found && ELEMENT.equals(name)) { found = true; // get the various attributes.. int count = xrdr.getAttributeCount(); for (int x = 0; x < count; x++) { name = xrdr.getAttributeLocalName(x); String value = xrdr.getAttributeValue(x); if (NAME.equals(name)) { setName(value); } } } else if (found && DataPoint.ELEMENT.equals(name)) { DataPoint dp = new DataPoint(); dp.fromXMLStream(xrdr); dataPoints.add(dp); } } else if (found && XMLStreamReader.END_ELEMENT == tag && ELEMENT.equals(xrdr.getLocalName())) { // we're done so stop parsing.. break; } } while (xrdr.next() != XMLStreamReader.END_DOCUMENT); } /* * (non-Javadoc) * * @see com.sun.idm.xml.XMLStreamObject#toXMLStream(javax.xml.stream.XMLStreamWriter) */ public void toXMLStream(XMLStreamWriter xwrt) throws XMLStreamException { xwrt.writeStartElement(ELEMENT); // write data set attributes if (name != null) { xwrt.writeAttribute(NAME, getName()); } // write out each data point for (Iterator iter = getDataPoints().iterator(); iter.hasNext();) { DataPoint dp = (DataPoint)iter.next(); dp.toXMLStream(xwrt); } xwrt.writeEndElement(); } } public static class ColorUtil { /** * Create the hex string representing a color. */ public static String colorToString(Color color) { int rgb = color.getRGB(); String value = Integer.toString(rgb); return value; } /** * Create a color object from a hex string. */ public static Color stringToColor(String color) { Color ret = Color.WHITE; try { ret = Color.decode(color); } catch (NumberFormatException e) { // do nothing.. } return ret; } } /** * String utilities.. */ public static class StringUtil { /** *
         *  StringUtil.isEmpty(null)               = true
         *  StringUtil.isEmpty("")       = true
         *  StringUtil.isEmpty(" ")      = false
         *  StringUtil.isEmpty("bob")    = false
         *  StringUtil.isEmpty(" bob ")  = false
         * 
*/ public static boolean isEmpty(String val) { return (val == null) ? true : "".equals(val) ? true : false; } public static boolean isNotEmpty(String val) { return !isEmpty(val); } /** *
         *      StringUtil.isBlank(null)                = true
         *      StringUtil.isBlank("")        = true
         *      StringUtil.isBlank(" ")       = true
         *      StringUtil.isBlank("bob")     = false
         *      StringUtil.isBlank("  bob  ") = false
         * 
*/ public static boolean isBlank(String val) { return (val == null) ? true : isEmpty(val.trim()); } public static boolean isNotBlank(String val) { return !isBlank(val); } } public static class EqualsBuilder { private boolean _equals = true; public EqualsBuilder() { // do nothing for now. } public EqualsBuilder appendSuper(boolean value) { // quick exit if already false.. if (isEquals()) { setEquals(value); } return this; } public EqualsBuilder append(Object lhs, Object rhs) { // quick exit if already false.. if (isEquals() == false) { return this; } // identity check.. if (lhs == rhs) { return this; } // this will check if one is null and the other is not.. if (lhs == null || rhs == null) { setEquals(false); return this; } // check that they are the same class.. Class rhsClass = rhs.getClass(); Class lhsClass = lhs.getClass(); if (rhsClass != lhsClass) { setEquals(false); } else if (!lhsClass.isArray()) { // The simple case, not an array, just test the element setEquals(lhs.equals(rhs)); } else if (lhs instanceof Set) { // get the arrays for each an test them.. } // 'Switch' on type of array, to dispatch to the correct handler // This handles multi dimensional arrays of the same depth else if (lhs instanceof long[]) { append((long[])lhs, (long[])rhs); } else if (lhs instanceof int[]) { append((int[])lhs, (int[])rhs); } else if (lhs instanceof short[]) { append((short[])lhs, (short[])rhs); } else if (lhs instanceof char[]) { append((char[])lhs, (char[])rhs); } else if (lhs instanceof byte[]) { append((byte[])lhs, (byte[])rhs); } else if (lhs instanceof double[]) { append((double[])lhs, (double[])rhs); } else if (lhs instanceof float[]) { append((float[])lhs, (float[])rhs); } else if (lhs instanceof boolean[]) { append((boolean[])lhs, (boolean[])rhs); } else { // Not an array of primitives append((Object[])lhs, (Object[])rhs); } return this; } public EqualsBuilder appendIgnoreCase(String lhs, String rhs) { if (isEquals() && lhs.equals(rhs)) { if (rhs == null) { setEquals(false); } else if (lhs.equalsIgnoreCase(rhs)) { setEquals(false); } } return this; } public EqualsBuilder append(long lhs, long rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(int lhs, int rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(short lhs, short rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(char lhs, char rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(byte lhs, byte rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(double lhs, double rhs) { if (_equals == false) { return this; } return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs)); } public EqualsBuilder append(float lhs, float rhs) { if (_equals == false) { return this; } return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs)); } public EqualsBuilder append(boolean lhs, boolean rhs) { if (isEquals() && lhs != rhs) { setEquals(false); } return this; } public EqualsBuilder append(Object[] lhs, Object[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(long[] lhs, long[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(int[] lhs, int[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(short[] lhs, short[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(char[] lhs, char[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(byte[] lhs, byte[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(double[] lhs, double[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(float[] lhs, float[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public EqualsBuilder append(boolean[] lhs, boolean[] rhs) { if (isEquals() && lhs != rhs) { if (lhs == null || rhs == null) { setEquals(false); } else if (lhs.length != rhs.length) { setEquals(false); } else { for (int i = 0; i < lhs.length && isEquals(); ++i) { append(lhs[i], rhs[i]); } } } return this; } public boolean isEquals() { return _equals; } protected void setEquals(boolean value) { _equals = value; } } public static class HashCodeBuilder { private final int _constant; /** * Running total used to produce hash code. */ private int _total = 0; public HashCodeBuilder() { _constant = 37; _total = 17; } public HashCodeBuilder append(boolean value) { _total = _total * _constant + (value ? 0 : 1); return this; } public HashCodeBuilder append(boolean[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(byte value) { _total = _total * _constant + value; return this; } public HashCodeBuilder append(byte[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(char value) { _total = _total * _constant + value; return this; } public HashCodeBuilder append(char[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(double value) { return append(Double.doubleToLongBits(value)); } public HashCodeBuilder append(double[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(float value) { _total = _total * _constant + Float.floatToIntBits(value); return this; } public HashCodeBuilder append(float[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(int value) { _total = _total * _constant + value; return this; } public HashCodeBuilder append(int[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(long value) { _total = _total * _constant + ((int)(value ^ (value >> 32))); return this; } public HashCodeBuilder append(long[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(Object object) { if (object == null) { _total = _total * _constant; } else { if (!object.getClass().isArray()) { // the simple case, not an array, just the element _total = _total * _constant + object.hashCode(); } else { // 'Switch' on type of array, to dispatch to the correct // handler // This handles multi dimensional arrays if (object instanceof long[]) { append((long[])object); } else if (object instanceof int[]) { append((int[])object); } else if (object instanceof short[]) { append((short[])object); } else if (object instanceof char[]) { append((char[])object); } else if (object instanceof byte[]) { append((byte[])object); } else if (object instanceof double[]) { append((double[])object); } else if (object instanceof float[]) { append((float[])object); } else if (object instanceof boolean[]) { append((boolean[])object); } else { // Not an array of primitives append((Object[])object); } } } return this; } public HashCodeBuilder append(Object[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder append(short value) { _total = _total * _constant + value; return this; } public HashCodeBuilder append(short[] array) { if (array == null) { _total = _total * _constant; } else { for (int i = 0; i < array.length; i++) { append(array[i]); } } return this; } public HashCodeBuilder appendSuper(int value) { _total = _total * _constant + value; return this; } public int toHashCode() { return _total; } } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/json/000077500000000000000000000000001440405772200251035ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/json/JSONArrayTest.java000066400000000000000000000052001440405772200303530ustar00rootroot00000000000000package org.codehaus.jettison.json; import junit.framework.TestCase; import java.util.ArrayList; import java.util.List; public class JSONArrayTest extends TestCase { public void testInvalidArraySequence() throws Exception { try { new JSONArray("[32,"); fail("Exception expected"); } catch (JSONException ex) { assertTrue(ex.getMessage().startsWith("JSONArray text has a trailing ','")); } } public void testInvalidArraySequence2() throws Exception { try { new JSONArray("[32,34"); fail("Exception expected"); } catch (JSONException ex) { assertTrue(ex.getMessage().startsWith("Expected a ',' or ']'")); } } public void testEscapingInArrayIsOnByDefault() { JSONArray array = new JSONArray(); array.put("a string with / character"); String expectedValue = "[\"a string with \\/ character\"]"; assertEquals(expectedValue, array.toString()); } public void testEscapingInArrayIsTrunedOff() throws JSONException { JSONObject obj = new JSONObject(); obj.put("key", "http://example.com/foo"); obj.setEscapeForwardSlashAlways(false); JSONArray array = new JSONArray(); array.put("a string with / character"); array.put(obj); array.setEscapeForwardSlashAlways(false); System.out.println(array.toString()); String expectedValue = "[\"a string with / character\",{\"key\":\"http://example.com/foo\"}]"; assertEquals(expectedValue, array.toString()); } public void testInfiniteLoop() { String str = "[*/*A25] **"; try { new JSONArray(str); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testInfiniteLoop2() { String str = "[/"; try { new JSONArray(str); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testIssue52() throws JSONException { JSONObject.setGlobalRecursionDepthLimit(10); new JSONArray("[{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {a:10}]"); JSONObject.setGlobalRecursionDepthLimit(500); } // https://github.com/jettison-json/jettison/issues/60 public void testIssue60() throws JSONException { List list = new ArrayList<>(); list.add(list); try { new JSONArray(list); } catch (JSONException ex) { assertEquals(ex.getMessage(), "JSONArray has reached recursion depth limit of 500"); } } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/json/JSONObjectTest.java000066400000000000000000000175531440405772200305210ustar00rootroot00000000000000package org.codehaus.jettison.json; import junit.framework.TestCase; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JSONObjectTest extends TestCase { public void testEquals() throws Exception { JSONObject aJsonObj = new JSONObject("{\"x\":\"y\"}"); JSONObject bJsonObj = new JSONObject("{\"x\":\"y\"}"); assertEquals(aJsonObj,bJsonObj); } public void testToLong() throws Exception { String json = "{\"key\":\"10001325703114005\"}"; JSONObject jsonObject = new JSONObject(json); long actual = jsonObject.getLong("key"); long expected = 10001325703114005L; assertTrue(expected < Long.MAX_VALUE); assertEquals(expected, actual); } public void testNotEquals() throws Exception { JSONObject aJsonObj = new JSONObject("{\"x\":\"y\"}"); JSONObject bJsonObj = new JSONObject("{\"x\":\"b\"}"); assertTrue(!aJsonObj.equals(bJsonObj)); } public void testAppend() throws Exception { JSONObject obj = new JSONObject(); obj.append("arr", "val1"); obj.append("arr", "val2"); obj.append("arr", "val3"); assertEquals("{\"arr\":[\"val1\",\"val2\",\"val3\"]}", obj.toString()); } public void testInvalidArraySequence() throws Exception { try { new JSONObject("{\"a\":["); fail("Exception expected"); } catch (JSONException ex) { assertTrue(ex.getMessage().startsWith("JSONArray text must end with ']'")); } } public void testInvalidArraySequence2() throws Exception { try { new JSONObject("{\"a\":[,"); fail("Exception expected"); } catch (JSONException ex) { assertTrue(ex.getMessage().startsWith("JSONArray text has a trailing ','")); } } public void testInvalidArraySequence3() throws Exception { String corruptedJSON = "{\"a\":[[\"b\",{\"revision\": 760839}],"; try { new JSONObject(corruptedJSON); fail("Exception expected"); } catch (JSONException ex) { assertTrue(ex.getMessage().startsWith("JSONArray text has a trailing ','")); } } public void testNullInQuotesGetString() throws Exception { JSONObject obj = new JSONObject("{\"a\":\"null\"}"); assertEquals("null", obj.getString("a")); } public void testExplicitNullGetString() throws Exception { JSONObject obj = new JSONObject("{\"a\":null}"); assertNull(obj.getString("a")); } public void testExplicitNullIsNull() throws Exception { JSONObject obj = new JSONObject("{\"a\":null}"); assertTrue(obj.isNull("a")); } public void testMissingIsNull() throws Exception { JSONObject obj = new JSONObject("{\"a\":null}"); assertTrue(obj.isNull("b")); } public void testSlashEscapingTurnedOnByDefault() throws Exception { JSONObject obj = new JSONObject(); obj.put("key", "http://example.com/foo"); assertEquals("{\"key\":\"http:\\/\\/example.com\\/foo\"}", obj.toString()); obj = new JSONObject(); obj.put("key", "\\\\"); assertEquals("{\"key\":\"\\\\\\\\\"}", obj.toString()); } public void testForwardSlashEscapingModifiedfBySetter() throws Exception { JSONObject obj = new JSONObject(); obj.put("key", "http://example.com/foo"); assertEquals(obj.toString(), "{\"key\":\"http:\\/\\/example.com\\/foo\"}"); obj.setEscapeForwardSlashAlways(false); assertEquals(obj.toString(), "{\"key\":\"http://example.com/foo\"}"); obj.setEscapeForwardSlashAlways(true); assertEquals(obj.toString(), "{\"key\":\"http:\\/\\/example.com\\/foo\"}"); } public void testMalformedObject() throws Exception { try { new JSONObject("{/"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testMalformedObject2() throws Exception { try { new JSONObject("{x"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testMalformedObject3() throws Exception { try { new JSONObject("{/x"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testMalformedObject4() throws Exception { try { new JSONObject("{/*"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testMalformedObject5() throws Exception { try { new JSONObject("{//"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } public void testMalformedArray() throws Exception { try { new JSONObject("{[/"); fail("Failure expected on malformed JSON"); } catch (JSONException ex) { // expected } } // https://github.com/jettison-json/jettison/issues/52 public void testIssue52() throws Exception { Map map = new HashMap<>(); map.put("t",map); new JSONObject(map); } // https://github.com/jettison-json/jettison/issues/52 public void testIssue52Recursive() throws Exception { try { Map map = new HashMap<>(); Map map2 = new HashMap<>(); map.put("t", map2); map2.put("t", map); new JSONObject(map); fail("Failure expected"); } catch (JSONException e) { assertTrue(e.getMessage().contains("JSONObject has reached recursion depth limit")); // expected } } // https://github.com/jettison-json/jettison/issues/45 public void testFuzzerTestCase() throws Exception, JSONException { try { new JSONObject("{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\"G\":[30018084,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,38,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,0]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,340282366920938463463374607431768211458,6,1,1]}:[32768,1,1,6,1,0]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,340282366920938463463374607431768211458,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,9 68,1,127,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,9223372036854775807]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,10,32768,1,1,6,1,1]}"); fail("Failure expected"); } catch (JSONException ex) { // expected assertTrue(ex.getMessage().contains("Expected a key")); } } public void testFuzzerTestCase2() throws Exception { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100000; i++) { sb.append("{\"key\":"); } try { new JSONObject(sb.toString()); fail("Failure expected"); } catch (JSONException e) { assertTrue(e.getMessage().contains("JSONTokener has reached recursion depth limit")); // expected } } public void testIssue58() throws JSONException { Map map = new HashMap<>(); map.put("request", "{\"exclude\":[\".\",\"?\",\"+\",\"*\",\"|\",\"{\",\"}\",\"[\",\"]\",\"(\",\")\",\"\\\"\",\"\\\\\",\"#\",\"@\",\"&\",\"<\",\">\",\"~\"]}"); JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject1 = new JSONObject(jsonObject.toString()); } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/json/JSONTokenerTest.java000066400000000000000000000015671440405772200307200ustar00rootroot00000000000000package org.codehaus.jettison.json; import java.math.BigDecimal; import junit.framework.TestCase; public class JSONTokenerTest extends TestCase { public void testDoublePrecision() throws Exception { JSONTokener doubleTokener = new JSONTokener("9999999999999.9999"); Object nextValue = doubleTokener.nextValue(); assertEquals(Double.class, nextValue.getClass()); assertEquals(Double.valueOf("1.0E13"), nextValue); } public void testBigDecimalPrecision() throws Exception { JSONTokener bigDecimalTokener = new JSONTokener("9999999999999.9999") { { this.useBigDecimal = true; } }; Object nextValue = bigDecimalTokener.nextValue(); assertEquals(BigDecimal.class, nextValue.getClass()); assertEquals(new BigDecimal("9999999999999.9999"), nextValue); } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/000077500000000000000000000000001440405772200254005ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/BootstrapTypeConverterTest.java000066400000000000000000000034671440405772200336240ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import junit.framework.TestCase; import org.codehaus.jettison.AbstractXMLStreamWriter; import java.io.StringWriter; public class BootstrapTypeConverterTest extends TestCase { public void testBootstrapConverter() throws Exception { Configuration cfg = new Configuration(); cfg.setTypeConverter(new ReplacementTypeConverter()); StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(cfg); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeCharacters("Not success"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String expected = "{\"root\":{\"subchild1\":\"success\"}}"; String actual = strWriter.toString(); assertEquals(expected, actual); } public static class ReplacementTypeConverter implements TypeConverter { public Object convertToJSONPrimitive( String text ) { return "success"; } } }DefaultTypeConverterEnforcedIntegerTest.java000066400000000000000000000043741440405772200361360ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import junit.framework.TestCase; import org.codehaus.jettison.AbstractXMLStreamWriter; import java.io.StringWriter; public class DefaultTypeConverterEnforcedIntegerTest extends TestCase { /** * @see DefaultTypeConverterUnenforcedIntegerTest */ public void testPrimitiveEnforcedInteger() throws Exception { Configuration cfg = new Configuration(); DefaultConverter converter = new DefaultConverter(); converter.setEnforce32BitInt(true); cfg.setTypeConverter(converter); StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(cfg); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeCharacters(Integer.MAX_VALUE + ""); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters(Integer.MIN_VALUE + ""); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters(Long.MAX_VALUE + ""); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters(Long.MIN_VALUE + ""); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String expected = "{\"root\":{\"subchild1\":[" + Integer.MAX_VALUE + "," + Integer.MIN_VALUE + ",\"" + Long.MAX_VALUE + "\",\"" + Long.MIN_VALUE + "\"]}}"; String actual = strWriter.toString(); assertEquals(expected, actual); } }DefaultTypeConverterUnenforcedIntegerTest.java000066400000000000000000000035231440405772200364740ustar00rootroot00000000000000jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import junit.framework.TestCase; import org.codehaus.jettison.AbstractXMLStreamWriter; import java.io.StringWriter; public class DefaultTypeConverterUnenforcedIntegerTest extends TestCase { /** * issue 61 * @see DefaultTypeConverterEnforcedIntegerTest */ public void testPrimitiveUnenforcedInteger() throws Exception { assertFalse( DefaultConverter.ENFORCE_32BIT_INTEGER ); StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeCharacters(Long.MAX_VALUE + ""); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters(Long.MIN_VALUE + ""); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String expected = "{\"root\":{\"subchild1\":[" + Long.MAX_VALUE + "," + Long.MIN_VALUE + "]}}"; String actual = strWriter.toString(); assertEquals(expected, actual); } }jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/MappedDOMTest.java000066400000000000000000000073271440405772200306620ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.Map; import org.codehaus.jettison.DOMTest; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Test Mapped DOM API * * @author Thomas.Diesler@jboss.com * @author Dejan Bosanac * @since 21-Mar-2008 */ public class MappedDOMTest extends DOMTest { public MappedDOMTest() throws Exception { super(); } public void testSimple() throws Exception { String xmlStr = "the frog"; String expStr = "{\"kermit\":\"the frog\"}"; String resStr = toJSON(parse(xmlStr), false); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr, false); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testSimpleAttribute() throws Exception { String xmlStr = "the frog"; String expStr = "{\"kermit\":{\"@mygirl\":\"piggy\",\"$\":\"the frog\"}}"; String resStr = toJSON(parse(xmlStr), false); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr, false); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testDefaultNamespace() throws Exception { String xmlStr = "the frog"; String expStr = "{\"somens.kermit\":\"the frog\"}"; String resStr = toJSON(parse(xmlStr), false); assertEquals("Unexpected result: " + resStr, expStr, resStr); String resXML = toXML(resStr, false); assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } public void testIgnoreNamespaces() throws Exception { String xmlStr = "2"; String expStr = "{\"A\":{\"B\":{\"@c\":1,\"$\":\"2\"}}}"; String resStr = toJSON(parse(xmlStr), true); assertEquals("Unexpected result: " + resStr, expStr, resStr); resStr="{\"somens.kermit\":\"the frog\"}"; String resXML = toXML(resStr, true); xmlStr = "the frog"; assertEquals("Unexpected result: " + resXML, xmlStr, resXML); } private String toJSON(Element srcDOM, boolean ignoreNamespaces) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Configuration conf = new Configuration(); conf.setIgnoreNamespaces(ignoreNamespaces); Map xnsToJns = new HashMap(); xnsToJns.put("http://somens", "somens"); conf.setXmlToJsonNamespaces(xnsToJns); new MappedDOMDocumentSerializer(baos, conf).serialize(srcDOM); return new String(baos.toByteArray()); } private String toXML(String jsonStr, boolean ignoreNamespaces) throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(jsonStr.getBytes()); Configuration conf = new Configuration(); conf.setIgnoreNamespaces(ignoreNamespaces); Map xnsToJns = new HashMap(); xnsToJns.put("http://somens", "somens"); conf.setXmlToJsonNamespaces(xnsToJns); Document resDOM = new MappedDOMDocumentParser(conf).parse(bais); return printNode(resDOM); } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/MappedXMLStreamReaderTest.java000066400000000000000000001332421440405772200331760ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.stream.Location; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import junit.framework.TestCase; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.codehaus.jettison.json.JSONTokener; public class MappedXMLStreamReaderTest extends TestCase { public void testStreamReader() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"child1\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testStreamReaderNullTextAsString() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"null\"" + "} }"); Configuration c = new Configuration(); c.setReadNullAsString(true); MappedNamespaceConvention con = new MappedNamespaceConvention(c); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("null", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testStreamReaderNullTextAsNull() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"null\"" + "} }"); Configuration c = new Configuration(); MappedNamespaceConvention con = new MappedNamespaceConvention(c); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals(null, reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testMultipleChildren() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"child1\"," + "\"child2\" : \"child2\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testMultipleChildrenWithSameName() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"child1\"," + "\"child1\" : \"child11\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child11", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testNestedArrayOfChildren() throws Exception { JSONObject obj = new JSONObject("{" + "\"root\":" + "{\"child1\":" + "[{\"subchild2\":" + "[\"first sub2\",\"second sub2\",\"third sub2\"]}" + ",\"sub1\",\"sub2\"]" + ",\"child2\":\"child2\"}" + "}"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("first sub2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("second sub2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("third sub2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("subchild2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("sub1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("sub2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testNamespaces() throws Exception { JSONObject obj = new JSONObject("{ " + "\"foo.root\" : { " + "\"foo.child1\" : \"childtext\"," + "} }"); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); MappedNamespaceConvention con = new MappedNamespaceConvention(new Configuration(xtoj)); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("childtext", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); } public void testDefaultNamespace() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : \"childtext\"," + "} }"); Map xtoj = new HashMap(); xtoj.put("http://foo/", ""); MappedNamespaceConvention con = new MappedNamespaceConvention( new Configuration(xtoj)); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("childtext", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals("http://foo/", reader.getName().getNamespaceURI()); } public void testArrayWithSameJSONObjects() throws Exception { String str = "{\"theBook\":" + "{" + "\"Names\":[{\"Name\":\"1\"}, {\"Name\":\"2\"}]" + " } " + "} "; Configuration config = new Configuration(); config.setPrimitiveArrayKeys(Collections.singleton("Names")); MappedXMLInputFactory factory = new MappedXMLInputFactory(config); XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(str)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Names", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Names", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); } public void testArrayWithSameJSONObjects2() throws Exception { String str = "{\"theBook\":[{\"Name\":\"1\"}, {\"Name\":\"2\"}]}"; Configuration config = new Configuration(); config.setPrimitiveArrayKeys(Collections.singleton("theBook")); MappedXMLInputFactory factory = new MappedXMLInputFactory(config); XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(str)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); } public void testArrayWithSameJSONObjects3() throws Exception { String str = "{\"theBook\":" + "{" + "\"Names\":[" + "{\"Name\":[{\"value\":\"11\"}, {\"value\":\"12\"}]}," + "{\"Name\":[{\"value\":\"21\"}, {\"value\":\"22\"}]}" + "]}" + "} "; Configuration config = new Configuration(); Set set = new HashSet(); set.add("Names"); set.add("Name"); config.setPrimitiveArrayKeys(set); MappedXMLInputFactory factory = new MappedXMLInputFactory(config); XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(str)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Names", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("11", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("12", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("21", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("22", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Names", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); } public void testExceptionLocation() throws Exception { String str = "{\"junk"; Configuration config = new Configuration(); MappedXMLInputFactory factory = new MappedXMLInputFactory(config); try { factory.createXMLStreamReader(new StringReader(str)); fail("Exception expected"); } catch (XMLStreamException ex) { Location loc = ex.getLocation(); assertNotNull(loc); assertEquals(0, loc.getLineNumber()); assertEquals(6, loc.getColumnNumber()); } } public void testArrayWithNotSameJSONObjects() throws Exception { String str = "{\"theBook\":[{\"Name\":\"1\"}, {\"Bar\":\"2\"}]}"; Configuration config = new Configuration(); config.setPrimitiveArrayKeys(Collections.singleton("theBook")); MappedXMLInputFactory factory = new MappedXMLInputFactory(config); XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(str)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Name", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("Bar", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("2", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("Bar", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("theBook", reader.getName().getLocalPart()); } public void testMultipleArrays() throws Exception { JSONObject obj = new JSONObject("{ \"root\": " + " [ " + " { " + " \"relationships\":[\"friend\"] , " + " \"emails\":[{\"value\":\"f@foo.com\"},{\"value\":\"b@bar.com\"}] " + " } " + " ] " + " } "); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("relationships", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("friend", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("relationships", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("emails", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("f@foo.com", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("emails", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("emails", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("b@bar.com", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("value", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("emails", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testSingleArrayWithOneElement() throws Exception { JSONObject obj = new JSONObject("{ \"root\": " + " [ " + " { " + " \"relationship\":\"friend\" , " + " \"email\":\"f@foo.com\" " + " } " + " , " + " { " + " \"relationship\":\"relative\" , " + " \"email\":\"b@foo.com\" " + " } " + " ] " + " } "); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("relationship", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("friend", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("relationship", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("email", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("f@foo.com", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("email", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("relationship", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("relative", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("relationship", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("email", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("b@foo.com", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("email", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testStreamReaderWithNullValue() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"child1\" : null" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(null, reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testGetElementTextNull() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : null }"); Configuration conf = new Configuration(); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(null, reader.getElementText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); } public void testAttributes() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"@att\" : \"attvalue\"," + "\"child1\" : \"child1\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("att", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("attvalue", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testAttributesAsElements() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"@att\" : \"attvalue\"," + "\"att2\" : \"attvalue\"," + "\"child1\" : \"child1\"" + "} }"); List atts = new ArrayList(); atts.add(new QName("att2")); Configuration c = new Configuration(); c.setAttributesAsElements(atts); MappedNamespaceConvention con = new MappedNamespaceConvention(c); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("att", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("attvalue", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("att2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("attvalue", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } public void testElementNameWithDot() throws Exception { JSONObject obj = new JSONObject("{ " + "\"org.codehaus.jettison.mapped.root\" : { " + "\"org.codehaus.jettison.mapped.child1\" : \"org.codehaus.jettison.mapped.child1\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("org.codehaus.jettison.mapped.root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("org.codehaus.jettison.mapped.child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("org.codehaus.jettison.mapped.child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("org.codehaus.jettison.mapped.child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("org.codehaus.jettison.mapped.root", reader.getName().getLocalPart()); } public void testNonStringObjects() throws Exception { JSONObject obj = new JSONObject("{\"root\":{\"foo\":true, \"foo2\":3.14, \"foo3\":17}}"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("foo", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("true", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("foo2", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("3.14", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("foo3", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("17", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); } public void testNonStringAttributes() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"@att\" : 1," + "\"child1\" : \"child1\"" + "} }"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("att", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("1", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } // issue 29 public void testComplexElements() throws Exception { JSONObject obj = new JSONObject("{\"a\":{\"o\":{\"@class\":\"string\",\"$\":\"1\"}}}"); MappedNamespaceConvention con = new MappedNamespaceConvention(); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("a", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("o", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("class", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("string", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("$", reader.getName().getLocalPart()); assertEquals("1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.END_DOCUMENT, reader.next()); } // issue 29 public void testIgnoreComplexElements() throws Exception { JSONObject obj = new JSONObject("{\"a\":{\"o\":{\"@class\":\"string\",\"$\":\"1\"}}}"); MappedNamespaceConvention con = new MappedNamespaceConvention(); MappedXMLStreamReader reader = new MappedXMLStreamReader(obj, con); reader.setValueKey(null); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("a", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("o", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("class", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("string", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("$", reader.getName().getLocalPart()); assertEquals("1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals(XMLStreamReader.END_DOCUMENT, reader.next()); } // issue 16 public void testSimple() throws Exception { JSONObject obj = new JSONObject("{\"root\":\"json string\"}"); MappedNamespaceConvention con = new MappedNamespaceConvention(); MappedXMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("json string", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); } //issue 52 public void testAttributeKey() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : { " + "\"!att\" : \"attvalue\"," + "\"child1\" : \"child1\"" + "} }"); Configuration conf = new Configuration(); conf.setAttributeKey("!"); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals(1, reader.getAttributeCount()); assertEquals("att", reader.getAttributeLocalName(0)); assertEquals("", reader.getAttributeNamespace(0)); assertEquals("attvalue", reader.getAttributeValue(0)); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.CHARACTERS, reader.next()); assertEquals("child1", reader.getText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("child1", reader.getName().getLocalPart()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); } //issue 50 public void testGetElementText() throws Exception { JSONObject obj = new JSONObject("{ " + "\"root\" : \"test\" }"); Configuration conf = new Configuration(); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); XMLStreamReader reader = new MappedXMLStreamReader(obj, con); assertEquals(XMLStreamReader.START_ELEMENT, reader.next()); assertEquals("root", reader.getName().getLocalPart()); assertEquals("test", reader.getElementText()); assertEquals(XMLStreamReader.END_ELEMENT, reader.next()); } // Issue 59 public void testListOfObject() throws Exception { String json = "{\"folders\":{" + "\"folder\" : [" + "{" + "\"name\":\"folder1\"," + "\"subfolder\":" + "[" + "{\"name\":\"subfolder1\"}," + "{\"name\":\"subfolder2\"}" + "]," + "\"file\":" + "[" + "{\"name\":\"file1\"}," + "{\"name\":\"file2\"}" + "]" + "}," + "]" + "}}"; // Expected XML String expXml = "" + "" + "folder1" + "" + "subfolder1" + "" + "" + "subfolder2" + "" + "" + "file1" + "" + "" + "file2" + "" + "" + ""; doTestEvents(json, expXml); } private void doTestEvents(String json, String expXml) throws JSONException, XMLStreamException, FactoryConfigurationError { JSONObject obj = new JSONObject(new JSONTokener(json)); Configuration config = new Configuration(); ArrayList refEvents = new ArrayList(); // reference reader XMLStreamReader refReader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(expXml)); while (refReader.hasNext()) { refEvents.add(Integer.valueOf(refReader.next())); } refReader.close(); // tested reader MappedXMLStreamReader mpdReader = new MappedXMLStreamReader(obj, new MappedNamespaceConvention(config)); ArrayList mpdEvents = new ArrayList(); StringBuilder sb = new StringBuilder(); while (mpdReader.hasNext()) { int eventType = mpdReader.next(); mpdEvents.add(Integer.valueOf(eventType)); if (eventType == XMLStreamConstants.START_ELEMENT) { sb.append("<").append(mpdReader.getName()).append(">"); } else if (eventType == XMLStreamConstants.CHARACTERS) { sb.append(mpdReader.getTextCharacters()); } else if (eventType == XMLStreamConstants.END_ELEMENT) { sb.append(""); } } mpdReader.close(); String mpdXml = sb.toString(); assertEquals(expXml, mpdXml); assertEquals(refEvents, mpdEvents); } } jettison-jettison-1.5.4/src/test/java/org/codehaus/jettison/mapped/MappedXMLStreamWriterTest.java000066400000000000000000001253501440405772200332510ustar00rootroot00000000000000/** * Copyright 2006 Envoi Solutions LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.jettison.mapped; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import org.codehaus.jettison.AbstractXMLStreamWriter; import junit.framework.TestCase; public class MappedXMLStreamWriterTest extends TestCase { public void testRoot() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":\"\"}", strWriter.toString()); } public void testChild() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"\"}}", strWriter.toString()); } public void testChildDropElement() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); c.setDropRootElement(true); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"child\":\"\"}", strWriter.toString()); } public void testChildDropElement2() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); c.setDropRootElement(true); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("root2"); w.writeStartElement("child"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root2\":{\"child\":\"\"}}", strWriter.toString()); } public void testChildDropElement3() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); List ignoredElements = new LinkedList(); ignoredElements.add("root"); ignoredElements.add("root2"); c.setIgnoredElements(ignoredElements); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("root2"); w.writeStartElement("child"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"child\":\"\"}", strWriter.toString()); } public void testChildDropElement4() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); List ignoredElements = new LinkedList(); ignoredElements.add("child"); c.setIgnoredElements(ignoredElements); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeEndElement(); w.writeStartElement("child2"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child2\":\"\"}}", strWriter.toString()); } public void testText() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters("test"); w.writeCharacters("test"); w.writeCharacters("test".toCharArray(), 0, 4); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"testtesttest\"}}", strWriter.toString()); } public void testTextEscapeForwardSlash() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); con.setEscapeForwardSlashAlways(true); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters("http://localhost:8080/json"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"http:\\/\\/localhost:8080\\/json\"}}", strWriter.toString()); } public void testTextForwardSlash() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters("http://localhost:8080/json"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"http://localhost:8080/json\"}}", strWriter.toString()); } public void testTextForwardSlashWithLeftAngle() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters(""); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"<\\/abc>\"}}", strWriter.toString()); } public void testTextForwardSlashFirstChar() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters("/abc"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"/abc\"}}", strWriter.toString()); } public void testTextNullAsString() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters(null); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":\"null\"}}", strWriter.toString()); } public void testTextNullAsNull() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); c.setWriteNullAsString(false); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters(null); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":null}}", strWriter.toString()); } public void testAttributes() throws Exception { StringWriter strWriter = new StringWriter(); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); MappedNamespaceConvention con = new MappedNamespaceConvention(new Configuration(xtoj)); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "attvalue"); w.writeAttribute("http://foo/", "att2", "attvalue"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"@att\":\"attvalue\",\"@foo.att2\":\"attvalue\"}}", strWriter.toString()); } public void testIntAttribute() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(new Configuration()); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "123"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"@att\":123}}", strWriter.toString()); } public void testIntAttributeAsString() throws Exception { StringWriter strWriter = new StringWriter(); Configuration c = new Configuration(); c.setTypeConverter(new SimpleConverter()); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "123"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"@att\":\"123\"}}", strWriter.toString()); } public void testAttributesAsElements() throws Exception { StringWriter strWriter = new StringWriter(); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); List atts = new ArrayList(); atts.add(new QName("http://foo/", "att2")); Configuration c = new Configuration(xtoj, atts, null); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "attvalue"); w.writeAttribute("http://foo/", "att2", "attvalue"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"@att\":\"attvalue\",\"foo.att2\":\"attvalue\"}}", strWriter.toString()); } public void testAttributesWithAtSupressed() throws Exception { StringWriter strWriter = new StringWriter(); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); List atts = new ArrayList(); atts.add(new QName("http://foo/", "att2")); Configuration c = new Configuration(xtoj, atts, null); c.setSupressAtAttributes(true); MappedNamespaceConvention con = new MappedNamespaceConvention(c); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "attvalue"); w.writeAttribute("http://foo/", "att2", "attvalue"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"att\":\"attvalue\",\"foo.att2\":\"attvalue\"}}", strWriter.toString()); } public void testTwoChildren() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child1"); w.writeEndElement(); w.writeStartElement("child2"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child1\":\"\",\"child2\":\"\"}}", strWriter.toString()); } public void testTwoChildrenWithSubChild() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child1"); w.writeStartElement("subchild"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("child2"); w.writeStartElement("subchild"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{" + "\"child1\":{\"subchild\":\"\"}," + "\"child2\":{\"subchild\":\"\"}}}", strWriter.toString()); } public void testTwoChildrenWithSubChildWithText() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child1"); w.writeStartElement("subchild1"); w.writeCharacters("test"); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters("test"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("child2"); w.writeStartElement("subchild"); w.writeCharacters("test"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{" + "\"child1\":{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "\"child2\":{\"subchild\":\"test\"}}}", strWriter.toString()); } public void testNestedArrayOfChildren() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeStartElement("subchild2"); w.writeCharacters("first sub2"); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeStartElement("subchild3"); w.writeCharacters("first sub3"); w.writeEndElement(); w.writeStartElement("subchild3"); w.writeCharacters("second sub3"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters("third sub2"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters("sub1"); w.writeEndElement(); //w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"subchild1\":[{\"subchild2\":[\"first sub2\",{\"subchild3\":[\"first sub3\",\"second sub3\"]},\"third sub2\"]},\"sub1\"]}}" , strWriter.toString()); } //ISSUE-48 public void testNestedArrayOfChildrenWithComplexElements() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeStartElement("subchild2"); w.writeCharacters("first sub2"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters("text"); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters("text1"); w.writeEndElement(); w.writeStartElement("outer"); w.writeCharacters("test"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals(strWriter.toString(), "{\"root\":{\"subchild1\":[{\"subchild2\":\"first sub2\"},\"text\",\"text1\"],\"outer\":\"test\"}}"); } public void testArrayOfChildren() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeCharacters("first"); w.writeEndElement(); w.writeStartElement("child"); w.writeCharacters("second"); w.writeEndElement(); w.writeStartElement("child"); w.writeCharacters("third"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("other"); w.writeCharacters("test"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":[\"first\",\"second\",\"third\"]},\"other\":\"test\"}", strWriter.toString()); } public void testMixedArrayAndJSONObject() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.serializeAsArray("results"); w.writeStartDocument(); w.writeStartElement("SearchResult"); w.writeStartElement("results"); w.writeStartElement("field"); w.writeCharacters("1"); w.writeEndElement(); w.writeStartElement("field"); w.writeCharacters("2"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("results"); w.writeStartElement("field"); w.writeCharacters("1"); w.writeEndElement(); w.writeStartElement("field"); w.writeCharacters("2"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("total"); w.writeCharacters("2"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"SearchResult\":{\"results\":[{\"field\":[1,2]},{\"field\":[1,2]}],\"total\":2}}", strWriter.toString()); } public void testMixedArrayAndJSONObject2() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("TestResult"); w.writeStartElement("company"); w.writeStartElement("name"); w.writeCharacters("Acme"); w.writeEndElement(); w.writeStartElement("phone"); w.writeStartElement("type"); w.writeCharacters("main"); w.writeEndElement(); w.writeStartElement("number"); w.writeCharacters("123"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("ceo"); w.writeStartElement("firstname"); w.writeCharacters("John"); w.writeEndElement(); w.writeStartElement("phone"); w.writeCharacters("567"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("address"); w.writeCharacters("Main st"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"TestResult\":{\"company\":{\"name\":\"Acme\",\"phone\":" + "{\"type\":\"main\",\"number\":123},\"ceo\":{\"firstname\":\"John\"," + "\"phone\":567},\"address\":\"Main st\"}}}", strWriter.toString()); } public void testComplexArrayOfChildren() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); addChild(w); addChild(w); addChild(w); addChild(w); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":[" + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}]}}", strWriter.toString()); } private void addChild(AbstractXMLStreamWriter w) throws XMLStreamException { w.writeStartElement("child"); w.writeStartElement("subchild1"); w.writeCharacters("test"); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters("test"); w.writeEndElement(); w.writeEndElement(); } public void testNamespacedElements() throws Exception { StringWriter strWriter = new StringWriter(); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); MappedNamespaceConvention con = new MappedNamespaceConvention(new Configuration(xtoj)); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("http://foo/", "root"); w.writeStartElement("http://foo/", "child"); w.writeEndElement(); w.writeStartElement("http://foo/", "child"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"foo.root\":{\"foo.child\":[\"\",\"\"]}}", strWriter.toString()); } public void testIssue18Enh() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("", "a", ""); w.writeStartElement("", "vals", ""); w.writeStartElement("", "string", ""); w.writeCharacters("1"); w.writeEndElement(); w.writeStartElement("", "string", ""); w.writeCharacters("2"); w.writeEndElement(); w.writeStartElement("", "string", ""); w.writeCharacters("3"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("", "n", ""); w.writeCharacters("5"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"a\":{\"vals\":{\"string\":[1,2,3]},\"n\":5}}", strWriter.toString()); } public void testMap() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("map"); w.writeStartElement("entry"); w.writeStartElement("string"); w.writeCharacters("id"); w.writeEndElement(); w.writeStartElement("string"); w.writeCharacters("6"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("entry"); w.writeStartElement("string"); w.writeCharacters("name"); w.writeEndElement(); w.writeStartElement("string"); w.writeCharacters("Dejan"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("entry"); w.writeStartElement("string"); w.writeCharacters("city"); w.writeEndElement(); w.writeStartElement("string"); w.writeCharacters("Belgrade"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String result = strWriter.toString(); assertEquals(result, "{\"map\":{\"entry\":[{\"string\":[\"id\",6]},{\"string\":[\"name\",\"Dejan\"]},{\"string\":[\"city\",\"Belgrade\"]}]}}"); } public void testPrimitiveTypes() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeStartElement("subchild2"); w.writeCharacters(5 + ""); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters(3.14 + ""); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters(true + ""); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters("000123"); w.writeEndElement(); w.writeStartElement("subchild2"); w.writeCharacters("Infinity"); w.writeEndElement(); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters("sub1"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String expected = "{\"root\":{\"subchild1\":[{\"subchild2\":[5,3.14,true,\"000123\",\"Infinity\"]},\"sub1\"]}}"; String actual = strWriter.toString(); assertEquals(expected, actual); } // issue 64 public void testPrimitiveInfinityNaN() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("subchild1"); w.writeCharacters("Infinity"); w.writeEndElement(); w.writeStartElement("subchild1"); w.writeCharacters("NaN"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); String expected = "{\"root\":{\"subchild1\":[\"Infinity\",\"NaN\"]}}"; String actual = strWriter.toString(); assertEquals(expected, actual); } //issue 29 public void testComplexElements() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("", "a", ""); w.writeStartElement("", "o", ""); w.writeAttribute("class", "string"); w.writeCharacters("1"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"a\":{\"o\":{\"@class\":\"string\",\"$\":\"1\"}}}", strWriter.toString()); } //issue 29 public void testIgnoreComplexElements() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); MappedXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.setValueKey(null); w.writeStartDocument(); w.writeStartElement("", "a", ""); w.writeStartElement("", "o", ""); w.writeAttribute("class", "string"); w.writeCharacters("1"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"a\":{\"o\":{\"@class\":\"string\"}}}", strWriter.toString()); } public void testSingleArrayElement() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.serializeAsArray(con.createKey("", "", "array-a")); w.writeStartDocument(); w.writeStartElement("", "array-a", ""); w.writeStartElement("", "a", ""); w.writeStartElement("", "n", ""); w.writeCharacters("1"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"array-a\":[{\"a\":{\"n\":1}}]}", strWriter.toString()); } public void testEmptySerializedArrayElement() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.serializeAsArray(con.createKey("", "", "array-a")); w.writeStartDocument(); w.writeStartElement("", "array-a", ""); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"array-a\":[\"\"]}", strWriter.toString()); } public void testNestedSerializedArrayElement() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.serializeAsArray(con.createKey("", "", "docs")); w.serializeAsArray(con.createKey("", "", "filters")); w.serializeAsArray(con.createKey("", "", "hosts")); w.writeStartDocument(); w.writeStartElement("", "docs", ""); w.writeStartElement("", "doc", ""); w.writeStartElement("", "id", ""); w.writeCharacters("24"); w.writeEndElement(); w.writeStartElement("", "filters", ""); w.writeEndElement(); w.writeStartElement("", "hosts", ""); w.writeStartElement("", "host", ""); w.writeStartElement("", "name", ""); w.writeCharacters("foobar.com"); w.writeEndElement(); //name w.writeStartElement("", "ip", ""); w.writeCharacters("255.255.255.255"); w.writeEndElement(); //ip w.writeEndElement(); // host w.writeEndElement(); //hosts w.writeEndElement(); // doc w.writeEndElement(); // docs w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"docs\":[{\"doc\":{\"id\":24,\"filters\":[\"\"],\"hosts\":[{\"host\":{\"name\":\"foobar.com\",\"ip\":\"255.255.255.255\"}}]}}]}", strWriter.toString()); } public void testSingleArrayElementIgnore() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("", "array-a", ""); w.writeStartElement("", "a", ""); w.writeStartElement("", "n", ""); w.writeCharacters("1"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"array-a\":{\"a\":{\"n\":1}}}", strWriter.toString()); } //issue 26 public void testArraysAndAttributes() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeStartElement("child"); w.writeAttribute("x", "y"); w.writeCharacters("value"); w.writeEndElement(); w.writeStartElement("child"); w.writeAttribute("a", "b"); w.writeCharacters("value"); w.writeEndElement(); w.writeStartElement("child"); w.writeAttribute("x", "z"); w.writeCharacters("value"); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"child\":[{\"@x\":\"y\",\"$\":\"value\"},{\"@a\":\"b\",\"$\":\"value\"},{\"@x\":\"z\",\"$\":\"value\"}]}}", strWriter.toString()); } //issue 36 public void testConverter() throws Exception { StringWriter strWriter = new StringWriter(); Configuration config = new Configuration(); config.setTypeConverter(new SimpleConverter()); MappedNamespaceConvention con = new MappedNamespaceConvention(config); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeCharacters("true"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":\"true\"}", strWriter.toString()); } //issue 52 public void testAttributeKey() throws Exception { StringWriter strWriter = new StringWriter(); Map xtoj = new HashMap(); xtoj.put("http://foo/", "foo"); Configuration conf = new Configuration(xtoj); conf.setAttributeKey("!"); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); w.writeAttribute("att", "attvalue"); w.writeAttribute("http://foo/", "att2", "attvalue"); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":{\"!att\":\"attvalue\",\"!foo.att2\":\"attvalue\"}}", strWriter.toString()); } // issue 63 public void testArrayAsFirstInAnArray() throws Exception { StringWriter strWriter = new StringWriter(); MappedNamespaceConvention con = new MappedNamespaceConvention(); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.serializeAsArray(con.createKey("", "", "bazs")); w.serializeAsArray(con.createKey("", "", "quacks")); w.writeStartDocument(); w.writeStartElement("Foo"); w.writeStartElement("bazs"); // array w.writeStartElement("quacks"); // array w.writeStartElement("goof"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"Foo\":{\"bazs\":[{\"quacks\":[{\"goof\":\"\"}]}]}}", strWriter.toString()); } // JETTISON-65 public void x_testImplicitCollections() throws Exception { StringWriter strWriter = new StringWriter(); Configuration conf = new Configuration(); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("root"); addChild(w); addChild(w); addChild(w); addChild(w); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"root\":[" + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}," + "{\"subchild1\":\"test\",\"subchild2\":\"test\"}]}", strWriter.toString()); } // JETTISON-57 public void testChildClassPropertyNameSameAsParentObject() throws Exception { StringWriter strWriter = new StringWriter(); Configuration conf = new Configuration(); MappedNamespaceConvention con = new MappedNamespaceConvention(conf); AbstractXMLStreamWriter w = new MappedXMLStreamWriter(con, strWriter); w.writeStartDocument(); w.writeStartElement("definition"); w.writeStartElement("structure"); w.writeAttribute("name", "conversation"); w.writeStartElement("symbolic"); w.writeAttribute("name", "reason"); w.writeEndElement(); w.writeStartElement("symbolic"); w.writeAttribute("name", "terms"); w.writeEndElement(); w.writeStartElement("numeric"); w.writeAttribute("name", "amountasked"); w.writeEndElement(); w.writeStartElement("numeric"); w.writeAttribute("name", "amountoffered"); w.writeEndElement(); w.writeStartElement("structure"); w.writeAttribute("name", "check"); w.writeStartElement("symbolic"); w.writeAttribute("name", "date"); w.writeEndElement(); w.writeStartElement("structure"); w.writeAttribute("name", "lines"); w.writeAttribute("repeating", "true"); w.writeStartElement("symbolic"); w.writeAttribute("name", "type"); w.writeEndElement(); w.writeStartElement("numeric"); w.writeAttribute("name", "amount"); w.writeEndElement(); w.writeStartElement("numeric"); w.writeAttribute("name", "cost"); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.close(); strWriter.close(); assertEquals("{\"definition\":" + "{\"structure\":{\"@name\":\"conversation\",\"symbolic\":" + "[{\"@name\":\"reason\"},{\"@name\":\"terms\"}],\"numeric\":[" + "{\"@name\":\"amountasked\"},{\"@name\":\"amountoffered\"}]," + "\"structure\":{\"@name\":\"check\",\"symbolic\":" + "{\"@name\":\"date\"},\"structure\":{\"@name\":\"lines\",\"@repeating\":true,\"symbolic\"" + ":{\"@name\":\"type\"},\"numeric\":[{\"@name\":\"amount\"},{\"@name\":\"cost\"}]}}}}}" , strWriter.toString()); } }