Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sebastian Baechle
committed
Mar 29, 2012
1 parent
79a9cc7
commit 7574df2
Showing
4 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* [New BSD License] | ||
* Copyright (c) 2011-2012, Brackit Project Team <info@brackit.org> | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* * Neither the name of the Brackit Project Team nor the | ||
* names of its contributors may be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
package org.brackit.xquery.function.io; | ||
|
||
import org.brackit.xquery.atomic.QNm; | ||
|
||
/** | ||
* @author Sebastian Baechle | ||
* | ||
*/ | ||
public class IOFun { | ||
public static final String IO_NSURI = "http://brackit.org/ns/io"; | ||
|
||
public static final String IO_PREFIX = "io"; | ||
|
||
public static final QNm IO_LOADFILE_INT_ERROR = new QNm(IO_NSURI, | ||
IO_PREFIX, "BIIO0001"); | ||
|
||
public static final QNm IO_WRITEFILE_INT_ERROR = new QNm(IO_NSURI, | ||
IO_PREFIX, "BIIO002"); | ||
|
||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/org/brackit/xquery/function/json/JSONFun.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* [New BSD License] | ||
* Copyright (c) 2011-2012, Brackit Project Team <info@brackit.org> | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* * Neither the name of the Brackit Project Team nor the | ||
* names of its contributors may be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
package org.brackit.xquery.function.json; | ||
|
||
import org.brackit.xquery.atomic.QNm; | ||
|
||
/** | ||
* @author Sebastian Baechle | ||
* | ||
*/ | ||
public class JSONFun { | ||
public static final String JSON_NSURI = "http://brackit.org/ns/json"; | ||
|
||
public static final String JSON_PREFIX = "json"; | ||
|
||
public static final QNm ERR_PARSING_ERROR = new QNm(JSON_NSURI, | ||
JSON_PREFIX, "BIJS0001"); | ||
} |
68 changes: 68 additions & 0 deletions
68
src/main/java/org/brackit/xquery/function/json/JSONParse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* [New BSD License] | ||
* Copyright (c) 2011-2012, Brackit Project Team <info@brackit.org> | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* * Neither the name of the Brackit Project Team nor the | ||
* names of its contributors may be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
package org.brackit.xquery.function.json; | ||
|
||
import org.brackit.xquery.QueryContext; | ||
import org.brackit.xquery.QueryException; | ||
import org.brackit.xquery.atomic.QNm; | ||
import org.brackit.xquery.atomic.Str; | ||
import org.brackit.xquery.function.AbstractFunction; | ||
import org.brackit.xquery.module.StaticContext; | ||
import org.brackit.xquery.xdm.Sequence; | ||
import org.brackit.xquery.xdm.Signature; | ||
import org.brackit.xquery.xdm.type.AtomicType; | ||
import org.brackit.xquery.xdm.type.Cardinality; | ||
import org.brackit.xquery.xdm.type.DocumentType; | ||
import org.brackit.xquery.xdm.type.SequenceType; | ||
|
||
/** | ||
* | ||
* @author Sebastian Baechle | ||
* | ||
*/ | ||
public class JSONParse extends AbstractFunction { | ||
|
||
public static final QNm PARSE = new QNm(JSONFun.JSON_NSURI, JSONFun.JSON_PREFIX, | ||
"parse"); | ||
|
||
public JSONParse() { | ||
super(PARSE, new Signature(new SequenceType(DocumentType.DOC, | ||
Cardinality.One), new SequenceType(AtomicType.STR, | ||
Cardinality.ZeroOrOne)), true); | ||
} | ||
|
||
@Override | ||
public Sequence execute(StaticContext sctx, QueryContext ctx, | ||
Sequence[] args) throws QueryException { | ||
Str s = (Str) args[0]; | ||
if (s == null) { | ||
return null; | ||
} | ||
return new JSONParser(s.stringValue()).parse(); | ||
} | ||
} |
215 changes: 215 additions & 0 deletions
215
src/main/java/org/brackit/xquery/function/json/JSONParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
/* | ||
* [New BSD License] | ||
* Copyright (c) 2011-2012, Brackit Project Team <info@brackit.org> | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* * Neither the name of the Brackit Project Team nor the | ||
* names of its contributors may be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
package org.brackit.xquery.function.json; | ||
|
||
import java.util.ArrayList; | ||
|
||
import org.brackit.xquery.QueryException; | ||
import org.brackit.xquery.array.DArray; | ||
import org.brackit.xquery.atomic.Bool; | ||
import org.brackit.xquery.atomic.Dbl; | ||
import org.brackit.xquery.atomic.Dec; | ||
import org.brackit.xquery.atomic.Int32; | ||
import org.brackit.xquery.atomic.Numeric; | ||
import org.brackit.xquery.atomic.QNm; | ||
import org.brackit.xquery.atomic.Str; | ||
import org.brackit.xquery.compiler.parser.Tokenizer; | ||
import org.brackit.xquery.record.ArrayRecord; | ||
import org.brackit.xquery.util.serialize.StringSerializer; | ||
import org.brackit.xquery.xdm.Item; | ||
|
||
/** | ||
* <p> | ||
* Simple recursive descent parser for JSON documents. | ||
* </p> | ||
* <p> | ||
* Note this parser is not 100% conform to the JSON RFC because we simply reuse | ||
* parts from the general (XQuery) {@link Tokenizer}. When we have time, we | ||
* should make it JSON conform. ;-) | ||
* </p> | ||
* | ||
* @author Sebastian Baechle | ||
* | ||
*/ | ||
public class JSONParser extends Tokenizer { | ||
|
||
public JSONParser(String query) { | ||
super(query); | ||
} | ||
|
||
public Item parse() throws QueryException { | ||
try { | ||
Item i = object(); | ||
i = (i != null) ? i : array(); | ||
if (i == null) { | ||
throw new QueryException(JSONFun.ERR_PARSING_ERROR, | ||
"No JSON data found"); | ||
} | ||
consumeEOF(); | ||
return i; | ||
} catch (IllegalCharRefException e) { | ||
throw new QueryException(e, JSONFun.ERR_PARSING_ERROR, e.getMessage()); | ||
} catch (Exception e) { | ||
throw new QueryException(e, JSONFun.ERR_PARSING_ERROR, e.getMessage()); | ||
} | ||
} | ||
|
||
protected void consumeSkipS(String token) throws TokenizerException { | ||
Token la = laSkipS(token); | ||
if (la == null) { | ||
throw new TokenizerException("Expected '%s': '%s'", token, | ||
paraphrase()); | ||
} | ||
consume(la); | ||
} | ||
|
||
private Item value(boolean required) throws TokenizerException, | ||
QueryException { | ||
Item i = string(); | ||
i = (i != null) ? i : number(); | ||
i = (i != null) ? i : object(); | ||
i = (i != null) ? i : array(); | ||
i = (i != null) ? i : symbol(required); | ||
return i; | ||
} | ||
|
||
private Item symbol(boolean required) throws TokenizerException { | ||
if (attemptSkipS("true")) { | ||
return Bool.TRUE; | ||
} else if (attemptSkipS("false")) { | ||
return Bool.FALSE; | ||
} else if (attemptSkipS("null")) { | ||
return null; | ||
} else if (required) { | ||
throw new TokenizerException("JSON value expected: %s", | ||
paraphrase()); | ||
} | ||
return null; | ||
} | ||
|
||
private Item array() throws TokenizerException, QueryException { | ||
if (!attemptSkipS("[")) { | ||
return null; | ||
} | ||
if (attemptSkipS("]")) { | ||
return new ArrayRecord(new QNm[0], new Item[0]); | ||
} | ||
ArrayList<Item> values = new ArrayList<Item>(); | ||
do { | ||
values.add(value(true)); | ||
} while (attemptSkipS(",")); | ||
consumeSkipS("]"); | ||
|
||
return new DArray(values.toArray(new Item[values.size()])); | ||
} | ||
|
||
private Item object() throws TokenizerException, QueryException { | ||
if (!attemptSkipS("{")) { | ||
return null; | ||
} | ||
if (attemptSkipS("}")) { | ||
return new ArrayRecord(new QNm[0], new Item[0]); | ||
} | ||
int len = 0; | ||
ArrayList<QNm> fields = new ArrayList<QNm>(); | ||
ArrayList<Item> values = new ArrayList<Item>(); | ||
do { | ||
Str name = string(); | ||
if (name == null) { | ||
|
||
} | ||
consumeSkipS(":"); | ||
Item value = value(true); | ||
fields.add(new QNm(null, null, name.stringValue())); | ||
values.add(value); | ||
len++; | ||
} while (attemptSkipS(",")); | ||
consumeSkipS("}"); | ||
|
||
return new ArrayRecord(fields.toArray(new QNm[len]), | ||
values.toArray(new Item[len])); | ||
} | ||
|
||
private Numeric number() throws QueryException, TokenizerException { | ||
Token la = laS(); | ||
if (la != null) { | ||
Token la2 = laInteger(la, true); | ||
if (la2 != null) { | ||
consume(la); | ||
consume(la2); | ||
return Int32.parse(la2.string()); | ||
} else if ((la2 = laDecimal(la, true)) != null) { | ||
consume(la); | ||
consume(la2); | ||
return new Dec(la2.string()); | ||
} else if ((la2 = laDouble(la, true)) != null) { | ||
consume(la); | ||
consume(la2); | ||
return new Dbl(la2.string()); | ||
} | ||
} else { | ||
la = laInteger(true); | ||
if (la != null) { | ||
consume(la); | ||
return Int32.parse(la.string()); | ||
} else if ((la = laDecimal(true)) != null) { | ||
consume(la); | ||
return new Dec(la.string()); | ||
} else if ((la = laDouble(true)) != null) { | ||
consume(la); | ||
return new Dbl(la.string()); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private Str string() throws TokenizerException { | ||
Token la = laS(); | ||
if (la != null) { | ||
Token la2 = laString(la, true); | ||
if (la2 != null) { | ||
consume(la); | ||
consume(la2); | ||
return new Str(la2.string()); | ||
} | ||
} else { | ||
la = laString(true); | ||
if (la != null) { | ||
consume(la); | ||
return new Str(la.string()); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public static void main(String[] args) throws Exception { | ||
String s = "{\"bindings\": [ {\"ircEvent\": \"PRIVMSG\", \"method\": \"newURI\", \"regex\": \"^http://.*\"}, {\"ircEvent\": \"PRIVMSG\", \"method\": \"deleteURI\", \"regex\": \"^delete.*\"}, {\"ircEvent\": \"PRIVMSG\", \"method\": \"randomURI\", \"regex\": \"^random.*\"} ]}"; | ||
Item item = new JSONParser(s).parse(); | ||
new StringSerializer(System.out).serialize(item); | ||
} | ||
} |