http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e428fa92/core/spi/src/main/java/org/json/JSONWriter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/json/JSONWriter.java b/core/spi/src/main/java/org/json/JSONWriter.java deleted file mode 100644 index c1328c0..0000000 --- a/core/spi/src/main/java/org/json/JSONWriter.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. - * - * 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.json; - -import java.io.IOException; -import java.io.Writer; - -/* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * 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. - * <p/> - * A JSONWriter instance provides a <code>value</code> method for appending - * values to the - * text, and a <code>key</code> - * method for adding keys before values in objects. There are <code>array</code> - * and <code>endArray</code> methods that make and bound array values, and - * <code>object</code> and <code>endObject</code> methods which make and bound - * object values. All of these methods return the JSONWriter instance, - * permitting a cascade style. For example, <pre> - * new JSONWriter(myWriter) - * .object() - * .key("JSON") - * .value("Hello, World!") - * .endObject();</pre> which writes <pre> - * {"JSON":"Hello, World!"}</pre> - * <p/> - * The first method called must be <code>array</code> or <code>object</code>. - * 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. - * <p/> - * This can sometimes be easier than using a JSONObject to build a string. - */ -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 JSONObject 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. - */ - public JSONWriter( Writer w ) - { - this.comma = false; - this.mode = 'i'; - this.stack = new JSONObject[ 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 - * <code>endArray</code> will be appended to this array. The - * <code>endArray</code> 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( null ); - 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 - * <code>array</code>. - * - * @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 - * <code>object</code>. - * - * @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 - { - stack[ top - 1 ].putOnce( s, Boolean.TRUE ); - 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 - * <code>endObject</code> will be appended to this object. The - * <code>endObject</code> 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( new JSONObject() ); - 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 ) - { - throw new JSONException( "Nesting error." ); - } - char m = this.stack[ this.top - 1 ] == null ? 'a' : 'k'; - if( m != c ) - { - throw new JSONException( "Nesting error." ); - } - this.top -= 1; - this.mode = this.top == 0 ? 'd' : this.stack[ this.top - 1 ] == null ? 'a' : 'k'; - } - - /** - * Push an array or object scope. - * - * @param jo The scope to open. - * - * @throws JSONException If nesting is too deep. - */ - private void push( JSONObject jo ) - throws JSONException - { - if( this.top >= maxdepth ) - { - throw new JSONException( "Nesting too deep." ); - } - this.stack[ this.top ] = jo; - this.mode = jo == null ? 'a' : 'k'; - this.top += 1; - } - - /** - * Append either the value <code>true</code> or the value - * <code>false</code>. - * - * @param b A boolean. - * - * @return this - * - * @throws 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 - */ - 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 ) ); - } - - /** - * Append JSON formatted string as-is - * - * @param json - * - * @return - * - * @throws JSONException - */ - public JSONWriter json( String json ) - throws JSONException - { - return this.append( json ); - } -} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e428fa92/core/spi/src/main/java/org/json/package.html ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/json/package.html b/core/spi/src/main/java/org/json/package.html deleted file mode 100644 index 6dc0ff7..0000000 --- a/core/spi/src/main/java/org/json/package.html +++ /dev/null @@ -1,8 +0,0 @@ -<html> - <body> - <h2>JSON in Java.</h2> - <p> - See <a href="http://www.json.org/java/">json.org/java</a>. - </p> - </body> -</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e428fa92/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationState.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationState.java b/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationState.java index 63413e7..9979ba5 100644 --- a/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationState.java +++ b/core/spi/src/main/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationState.java @@ -11,7 +11,6 @@ * limitations under the License. * */ - package org.qi4j.spi.entitystore.helpers; import java.util.Iterator; @@ -23,11 +22,13 @@ import org.qi4j.spi.entity.ManyAssociationState; import org.qi4j.spi.entitystore.EntityStoreException; /** - * JSON implementation of ManyAssociationState. Backed by JSONArray. + * JSON implementation of ManyAssociationState. + * <p>Backed by a JSONArray.</p> */ public final class JSONManyAssociationState implements ManyAssociationState { + private JSONEntityState entityState; private JSONArray references; @@ -46,21 +47,7 @@ public final class JSONManyAssociationState @Override public boolean contains( EntityReference entityReference ) { - try - { - for( int i = 0; i < references.length(); i++ ) - { - if( references.get( i ).equals( entityReference.identity() ) ) - { - return true; - } - } - return false; - } - catch( JSONException e ) - { - throw new EntityStoreException( e ); - } + return indexOfReference( entityReference.identity() ) != -1; } @Override @@ -68,12 +55,12 @@ public final class JSONManyAssociationState { try { - if( contains( entityReference ) ) + if( indexOfReference( entityReference.identity() ) != -1 ) { return false; } entityState.cloneStateIfGlobalStateLoaded(); - references.insert( idx, entityReference.identity() ); + insertReference( idx, entityReference.identity() ); entityState.markUpdated(); return true; } @@ -86,24 +73,15 @@ public final class JSONManyAssociationState @Override public boolean remove( EntityReference entityReference ) { - try + int refIndex = indexOfReference( entityReference.identity() ); + if( refIndex != -1 ) { - for( int i = 0; i < references.length(); i++ ) - { - if( references.get( i ).equals( entityReference.identity() ) ) - { - entityState.cloneStateIfGlobalStateLoaded(); - references.remove( i ); - entityState.markUpdated(); - return true; - } - } - return false; - } - catch( JSONException e ) - { - throw new EntityStoreException( e ); + entityState.cloneStateIfGlobalStateLoaded(); + references.remove( refIndex ); + entityState.markUpdated(); + return true; } + return false; } @Override @@ -124,7 +102,7 @@ public final class JSONManyAssociationState { return new Iterator<EntityReference>() { - int idx = 0; + private int idx = 0; @Override public boolean hasNext() @@ -154,4 +132,53 @@ public final class JSONManyAssociationState } }; } + + @Override + public String toString() + { + return references.toString(); + } + + private int indexOfReference( Object item ) + { + for( int idx = 0; idx < references.length(); idx++ ) + { + if( item.equals( references.opt( idx ) ) ) + { + return idx; + } + } + return -1; + } + + private void insertReference( int insert, Object item ) + throws JSONException + { + if( insert < 0 || insert > references.length() ) + { + throw new JSONException( "JSONArray[" + insert + "] is out of bounds." ); + } + if( insert == references.length() ) + { + // append + references.put( item ); + } + else + { + // insert (copy/insert/apply) + JSONArray output = new JSONArray(); + for( int idx = 0; idx < references.length(); idx++ ) + { + if( idx == insert ) + { + output.put( item ); + } + output.put( references.opt( idx ) ); + } + for( int idx = 0; idx < output.length(); idx++ ) + { + references.put( idx, output.opt( idx ) ); + } + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e428fa92/core/spi/src/test/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationStateTest.java ---------------------------------------------------------------------- diff --git a/core/spi/src/test/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationStateTest.java b/core/spi/src/test/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationStateTest.java new file mode 100644 index 0000000..3de0647 --- /dev/null +++ b/core/spi/src/test/java/org/qi4j/spi/entitystore/helpers/JSONManyAssociationStateTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, Paul Merlin. All Rights Reserved. + * + * 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.qi4j.spi.entitystore.helpers; + +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; +import org.qi4j.api.entity.EntityReference; +import org.qi4j.functional.Function; +import org.qi4j.spi.entity.EntityStatus; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertThat; +import static org.qi4j.functional.Iterables.map; +import static org.qi4j.functional.Iterables.toList; + +public class JSONManyAssociationStateTest +{ + + @Test + public void givenEmptyJSONManyAssociationStateWhenAddingTwoRefsAtZeroIndexExpectCorrectOrder() + throws JSONException + { + // Fake JSONManyAssociationState + JSONObject state = new JSONObject(); + state.put( JSONEntityState.JSON_KEY_PROPERTIES, new JSONObject() ); + state.put( JSONEntityState.JSON_KEY_ASSOCIATIONS, new JSONObject() ); + state.put( JSONEntityState.JSON_KEY_MANYASSOCIATIONS, new JSONObject() ); + JSONEntityState entityState = new JSONEntityState( null, + null, + "0", + System.currentTimeMillis(), + EntityReference.parseEntityReference( "123" ), + EntityStatus.NEW, + null, + state ); + JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() ); + + jsonState.add( 0, EntityReference.parseEntityReference( "first" ) ); + jsonState.add( 0, EntityReference.parseEntityReference( "second" ) ); + + assertThat( jsonState.count(), equalTo( 2 ) ); + } + + @Test + public void givenJSONManyAssociationStateWhenChangingReferencesExpectCorrectBehavior() + throws JSONException + { + // Fake JSONManyAssociationState + JSONObject state = new JSONObject(); + state.put( JSONEntityState.JSON_KEY_PROPERTIES, new JSONObject() ); + state.put( JSONEntityState.JSON_KEY_ASSOCIATIONS, new JSONObject() ); + state.put( JSONEntityState.JSON_KEY_MANYASSOCIATIONS, new JSONObject() ); + JSONEntityState entityState = new JSONEntityState( null, + null, + "0", + System.currentTimeMillis(), + EntityReference.parseEntityReference( "123" ), + EntityStatus.NEW, + null, + state ); + JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() ); + + assertThat( jsonState.contains( EntityReference.parseEntityReference( "NOT_PRESENT" ) ), is( false ) ); + + jsonState.add( 0, EntityReference.parseEntityReference( "0" ) ); + jsonState.add( 1, EntityReference.parseEntityReference( "1" ) ); + jsonState.add( 2, EntityReference.parseEntityReference( "2" ) ); + + assertThat( jsonState.contains( EntityReference.parseEntityReference( "1" ) ), is( true ) ); + + assertThat( jsonState.get( 0 ).identity(), equalTo( "0" ) ); + assertThat( jsonState.get( 1 ).identity(), equalTo( "1" ) ); + assertThat( jsonState.get( 2 ).identity(), equalTo( "2" ) ); + + assertThat( jsonState.count(), equalTo( 3 ) ); + + jsonState.remove( EntityReference.parseEntityReference( "1" ) ); + + assertThat( jsonState.count(), equalTo( 2 ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "1" ) ), is( false ) ); + assertThat( jsonState.get( 0 ).identity(), equalTo( "0" ) ); + assertThat( jsonState.get( 1 ).identity(), equalTo( "2" ) ); + + jsonState.add( 2, EntityReference.parseEntityReference( "1" ) ); + + assertThat( jsonState.count(), equalTo( 3 ) ); + + jsonState.add( 0, EntityReference.parseEntityReference( "A" ) ); + jsonState.add( 0, EntityReference.parseEntityReference( "B" ) ); + jsonState.add( 0, EntityReference.parseEntityReference( "C" ) ); + + assertThat( jsonState.count(), equalTo( 6 ) ); + + assertThat( jsonState.get( 0 ).identity(), equalTo( "C" ) ); + assertThat( jsonState.get( 1 ).identity(), equalTo( "B" ) ); + assertThat( jsonState.get( 2 ).identity(), equalTo( "A" ) ); + + assertThat( jsonState.contains( EntityReference.parseEntityReference( "C" ) ), is( true ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "B" ) ), is( true ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "A" ) ), is( true ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "0" ) ), is( true ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "2" ) ), is( true ) ); + assertThat( jsonState.contains( EntityReference.parseEntityReference( "1" ) ), is( true ) ); + + List<String> refList = toList( map( new Function<EntityReference, String>() + { + @Override + public String map( EntityReference from ) + { + return from.identity(); + } + }, jsonState ) ); + assertThat( refList.isEmpty(), is( false ) ); + assertArrayEquals( new String[] + { + "C", "B", "A", "0", "2", "1" + }, refList.toArray() ); + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/e428fa92/libraries.gradle ---------------------------------------------------------------------- diff --git a/libraries.gradle b/libraries.gradle index 2ac02fa..946563d 100644 --- a/libraries.gradle +++ b/libraries.gradle @@ -40,6 +40,7 @@ def mongodbVersion = '2.9.3' def mysqlVersion = '5.1.21' def neoVersion = '1.3' // 1.8 exists def neoIndexVersion = '1.3-1.3.M01' // Do not exist anymore! +def orgJsonVersion = '20130213' def osgiVersion = '4.2.0' // 4.3.0 - Fails to compile! def pdfboxVersion = '1.7.1' def postgresqlVersion = '9.1-901-1.jdbc4' @@ -101,6 +102,9 @@ rootProject.ext { jcl_api: 'commons-logging:commons-logging-api:99.0-does-not-exist', //ensure it is never used. jcl: 'commons-logging:commons-logging:99.0-does-not-exist', // ensure it is never used. + // org.json + org_json: "org.codeartisans:org.json:$orgJsonVersion", + // Restlet restlet: [ "org.restlet.jee:org.restlet:$restletVersion",
