Author: dkuleshov
Date: 2012-02-01 08:31:49 -0500 (Wed, 01 Feb 2012)
New Revision: 5552
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.g
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDWalker.g
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDNodeTypeDataPersister.java
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamReader.java
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamWriter.java
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/registration/
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.testsuite
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDNodeTypeRegistration.java
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDParser.java
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDSerialization.java
jcr/branches/1.15.x/exo.jcr.component.core/src/test/resources/cnd-reader-test-input.cnd
Modified:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java
Log:
EXOJCR-1108: added runtime node type registation in CND file format
* Added ANTLR grammar to pars CND format
* Added gUnit testsuite to test ANTLR grammars
* Added CNDNodeTypeDataPersister and all dependent classes
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.g
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.g
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.g 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+/*Compact NODE TYPE DEFINITION GRAMMAR*/
+
+grammar CND;
+
+options {
+ output = AST;
+}
+
+/*DEFINING VIRTUAL TOKENS*/
+tokens {
+ NAMESPACE;
+ PREFIX;
+ URI;
+ NODETYPEDEF;
+ NODETYPENAME;
+ SUPERTYPES;
+ NODETYPEATTRIBUTES;
+ ORDERABLE;
+ MIXIN;
+ ABSTRACT;
+ NOQUERY;
+ PRIMARYITEM;
+ PROPERTYDEF;
+ PROPERTYNAME;
+ PROPERTYTYPE;
+ DEFAULTVALUES;
+ PROPERTYATTRIBUTE;
+ AUTOCREATED;
+ MANDATORY;
+ PROTECTED;
+ OPV;
+ MULTIPLE;
+ QUERYOPS;
+ NOFULLTEXT;
+ NOQUERYORDER;
+ SNS;
+ VALUECONSTRAINTS;
+ CHILDDEF;
+ NODENAME;
+ REQUIREDTYPES;
+ DEFAULTTYPE;
+ NODEATTRIBUTE;
+}
+/* Parser's class header */
+@parser::header {
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import java.util.LinkedList;
+}
+/* Lexer's class header */
+@lexer::header{
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import java.util.LinkedList;
+}
+/* Parser's class members */
+@parser::members{
+
+private List<String> errors = new LinkedList<String>();
+@Override
+public void emitErrorMessage(String msg) {
+ super.emitErrorMessage(msg);
+ errors.add(msg);
+}
+public List<String> getErrors() {
+ return errors;
+}
+public boolean hasError(){
+ return (errors.size()>0);
+}
+
+class ParserRecognitionException extends RecognitionException {
+ private Throwable cause;
+ private String message;
+
+ public ParserRecognitionException(String message) {
+ this.message = message;
+ }
+
+ public Throwable getCause() {
+ return (cause==this ? null : cause);
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
+}
+/* Lexer's class members */
+@lexer::members {
+private List<String> errors = new LinkedList<String>();
+@Override
+public void emitErrorMessage(String msg) {
+ super.emitErrorMessage(msg);
+ errors.add(msg);
+}
+public List<String> getErrors() {
+ return errors;
+}
+public boolean hasError(){
+ return (errors.size()>0);
+}
+}
+
+
+/*======================================================*/
+/* PARSER RULES */
+/*======================================================*/
+
+/*Main loop*/
+cnd : (( namespace)|( nodetypedef))* EOF!;
+
+/*namespace definition*/
+namespace
+ : '<' prefix '=' uri '>'
+ -> ^(NAMESPACE prefix uri);
+prefix : name -> ^(PREFIX name);
+uri : STRING -> ^(URI STRING);
+
+/*NODETYPE DEFINITION*/
+nodetypedef
+ : nodetypename ( supertypes)? ( nodetypeattributes)? (( propertydef) | ( childnodedef))*
+ -> ^(NODETYPEDEF nodetypename supertypes? nodetypeattributes? propertydef*
childnodedef*) ;
+
+/*NODE TYPE DEFINITION PARTS*/
+nodetypename
+ : '[' name ']' -> ^(NODETYPENAME name);
+
+/*NODE TYPE SUPERTYPES*/
+supertypes
+ : '>' supertypeVal
+ -> ^(SUPERTYPES supertypeVal);
+supertypeVal
+ : (name ( ','! name)*)
+ | VARIANT;
+
+/*NODE TYPE ATTRIBUTES*/
+nodetypeattributes
+ : nodetypeattribute ( nodetypeattribute)*
+ -> ^(NODETYPEATTRIBUTES nodetypeattribute+);
+nodetypeattribute
+ : opt_orderable|opt_mixin|opt_abstract|opt_noquery|opt_primaryitem;
+
+/*NODETYPE OPTIONS*/
+opt_orderable
+ : (T_ORDERABLE|T_ORD|T_O) ( VARIANT)? -> ^(ORDERABLE VARIANT?);
+opt_mixin
+ : (T_MIXIN|T_MIX|T_M) ( VARIANT)? -> ^(MIXIN VARIANT?);
+opt_abstract
+ : (T_ABSTRACT|T_ABS|T_A) ( VARIANT)? -> ^(ABSTRACT VARIANT?);
+opt_noquery
+ : (T_NOQUERY|T_NQ) ( VARIANT)? -> ^(NOQUERY VARIANT?);
+opt_primaryitem
+ : (T_PRIMARY | '!') (v=STRING | v='?') -> ^(PRIMARYITEM $v);
+
+/*PROPERTY DEFINITION*/
+propertydef
+ : propertyname ( propertytype)? ( propertyparams)*
+ -> ^(PROPERTYDEF propertyname propertytype? propertyparams*);
+
+/*PROPERTY PARAMETERS*/
+propertyparams
+ : defaultvalues | propertyattributes | valueconstraints;
+propertyname
+ : '-' name -> ^(PROPERTYNAME name);
+propertytype
+ : '('propertytypes')' -> ^(PROPERTYTYPE propertytypes);
+propertytypes
+ : PT_STRING | PT_BINARY | PT_LONG | PT_DOUBLE | PT_BOOLEAN
+ | PT_DATE | PT_NAME | PT_PATH | PT_REFERENCE | PT_WEAKREFERENCE
+ | PT_DECIMAL | PT_URI
+ | PT_UNDEFINED
+ | '*' -> PT_UNDEFINED
+ | VARIANT;
+defaultvalues
+ : '=' defaultvalueslist -> ^(DEFAULTVALUES defaultvalueslist);
+defaultvalueslist
+ : (STRING ( ','! STRING)*)
+ | VARIANT;
+propertyattributes
+ : propertyattribute -> ^(PROPERTYATTRIBUTE propertyattribute);
+
+propertyattribute
+ : atr_autocreated | atr_mandatory | atr_protected | atr_OPV
+ | atr_multiple | atr_queryops | atr_nofulltext | atr_noqueryorder;
+
+/*PROPERTY ATTRIBUTES*/
+atr_autocreated
+ : (T_AUTOCREATED|T_AUT|T_A)( VARIANT)? -> ^(AUTOCREATED VARIANT?);
+atr_mandatory
+ : (T_MANDATORY|T_MAN|T_M) ( VARIANT)? -> ^(MANDATORY VARIANT?);
+atr_protected
+ : (T_PROTECTED|T_PRO|T_P) ( VARIANT)? -> ^(PROTECTED VARIANT?);
+atr_OPV : (T_OPV) -> ^(OPV T_OPV)
+ | (T_OPV_OPV v='?') -> ^(OPV VARIANT);
+atr_multiple
+ : (T_MULTIPLE|T_MUL|'*') ( VARIANT)? -> ^(MULTIPLE VARIANT?);
+atr_queryops
+ : (T_QUERYOPS|T_QOP) (operators) -> ^(QUERYOPS operators);
+
+/*Operators as strings.
+Tey should be recognized in TreeWalker*/
+operators: STRING | '?';
+
+atr_nofulltext
+ : (T_NOFULLTEXT|T_NOF) ( VARIANT)? -> ^(NOFULLTEXT VARIANT?);
+atr_noqueryorder
+ : (T_NOQUERYORDER|T_NQORD)( VARIANT)? -> ^(NOQUERYORDER VARIANT?);
+atr_sns
+ : (T_SNS|'*') ( VARIANT)? -> ^(SNS VARIANT?);
+
+/*Constraints*/
+valueconstraints
+ : '<' valueconstraintslist -> ^(VALUECONSTRAINTS
valueconstraintslist);
+valueconstraintslist
+ : (STRING ( ','! STRING)*)
+ | VARIANT;
+
+/*CHILD NODE DEFINITION*/
+childnodedef
+ : nodename ( requiredtypes)? ( defaulttype)? ( nodeattributes)*
+ -> ^(CHILDDEF nodename requiredtypes? defaulttype? nodeattributes*);
+nodename
+ : '+' name -> ^(NODENAME name);
+requiredtypes
+ : '(' requiredtypesVal ')' -> ^(REQUIREDTYPES requiredtypesVal);
+requiredtypesVal
+ : (name ( ','! name)*)
+ | VARIANT;
+defaulttype
+ : '=' defaulttypeVal -> ^(DEFAULTTYPE defaulttypeVal);
+defaulttypeVal
+ : name
+ | VARIANT;
+nodeattributes
+ : nodeattribute -> ^(NODEATTRIBUTE nodeattribute);
+nodeattribute
+ : atr_autocreated | atr_mandatory | atr_protected | atr_OPV | atr_sns;
+
+/*Allow names be strings or registered words*/
+name : STRING -> STRING
+ | registeredWords -> registeredWords;
+/* List of registred words */
+registeredWords
+ : T_ORDERABLE | T_ORD | T_O | T_MIXIN | T_MIX | T_M | T_ABSTRACT
+ | T_ABS | T_A | T_NOQUERY |T_NQ | T_AUTOCREATED | T_AUT | T_MANDATORY
+ | T_MAN | T_PROTECTED | T_PRO | T_P | T_OPV | T_OPV_OPV | T_PRIMARY
+ | T_MULTIPLE | T_MUL | T_QUERYOPS | T_QOP | T_NOFULLTEXT | T_NOF
+ | T_NOQUERYORDER | T_NQORD | T_SNS | PT_STRING | PT_BINARY | PT_LONG
+ | PT_DOUBLE | PT_BOOLEAN | PT_DATE | PT_NAME | PT_PATH | PT_REFERENCE
+ | PT_WEAKREFERENCE | PT_DECIMAL | PT_URI | PT_UNDEFINED;
+
+/*======================================================*/
+/* LEXER RULES */
+/*======================================================*/
+
+/*TERMINATORS AND OPERATORS*/
+EQUAL : '=';
+LESS : '<';
+MORE : '>';
+VARIANT : '?';
+LSBr : '[';
+RSBr : ']';
+LPAR : '(';
+RPAR : ')';
+PLUS : '+';
+MINUS : '-';
+QUOTE : '\'';
+//DOUBLEQUOTE: '"';
+PRIM : '!';
+
+/* Node type attributes */
+
+/*TOKEN ORDERABLE*/
+T_ORDERABLE
+ : O R D E R A B L E;//'orderable';
+T_ORD : O R D;//'ord';
+T_O : O;//'o';
+
+/*TOKEN MIXIN*/
+T_MIXIN : M I X I N;//
+T_MIX : M I X;//'mix';
+T_M : M;//'m'; //also: T_MANDATORY in short form
+
+/*TOKEN ABSTRACT*/
+T_ABSTRACT
+ : A B S T R A C T;//'abstract';
+T_ABS : A B S;//'abs';
+T_A : A;//'a'; //also:T_AUTOCREATED in short form
+
+/*TOKEN NO_QUERY*/
+T_NOQUERY
+ : N O Q U E R Y;//'noquery';
+T_NQ : N Q;//'nq';
+
+/*TOKEN PRIMARY*/
+T_PRIMARY
+ : P R I M A R Y I T E M; //('primaryitem' | '!');
+
+/*TOKEN AUTOCREATED*/
+T_AUTOCREATED
+ : A U T O C R E A T E D;//'autocreated';
+T_AUT : A U T;//'aut';
+
+/*TOKEN MANDATORY*/
+T_MANDATORY
+ : M A N D A T O R Y;//'mandatory';
+T_MAN : M A N;//'man';
+
+/*TOKEN PROTECTED*/
+T_PROTECTED
+ : P R O T E C T E D;//'protected';
+T_PRO : P R O;//'pro';
+T_P : P;//'p';
+
+/*TOKENS OPV*/
+T_OPV : (C O P Y)
+ | (V E R S I O N)
+ | (I N I T I A L I Z E)
+ | (C O M P U T E)
+ | (I G N O R E)
+ | (A B O R T);
+T_OPV_OPV
+ : (O P V);
+
+/*TOKEN MULTIPLE*/
+T_MULTIPLE
+ : M U L T I P L E;//'multiple';
+T_MUL : M U L;//'mul';
+
+/*QUERRY OPS*/
+T_QUERYOPS
+ : Q U E R Y O P S;//'queryops';
+T_QOP
+ : Q O P;//'qop';
+
+/*TOKEN NOFULLTEXT*/
+T_NOFULLTEXT
+ : N O F U L L T E X T;//'nofulltext';
+T_NOF : N O F;//'nof';
+
+/*TOKEN NOQUERYORDER*/
+T_NOQUERYORDER
+ : N O Q U E R Y O R D E R ;//'noqueryorder';
+T_NQORD : N Q O R D;//'nqord';
+
+/*SNS TOKEN*/
+T_SNS : S N S;//'sns';
+
+
+/*PROPERTY TYPES*/
+PT_STRING
+ : (S T R I N G);
+PT_BINARY
+ : (B I N A R Y);
+PT_LONG : (L O N G);
+PT_DOUBLE
+ : (D O U B L E);
+PT_BOOLEAN
+ : (B O O L E A N);
+PT_DATE : (D A T E);
+PT_NAME : (N A M E);
+PT_PATH : (P A T H);
+PT_REFERENCE
+ : (R E F E R E N C E);
+PT_WEAKREFERENCE
+ : (W E A K R E F E R E N C E);
+PT_DECIMAL
+ : (D E C I M A L);
+PT_URI : (U R I);
+PT_UNDEFINED
+ : (U N D E F I N E D)|'*';
+
+COMMENT
+ : '//' ~('\n'|'\r')* '\r'? '\n'
{$channel=HIDDEN;}
+ | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
+ ;
+
+STRING : QUOTEDSTRING
+ | UNQUOTEDSTRING
+ | DOUBLEQUOTEDSTRING
+ ;
+
+fragment DOUBLEQUOTEDSTRING
+ : '"' ( ESC_SEQ | ~('\\'|'"') )* '"';
+fragment QUOTEDSTRING
+ : QUOTE ( ESC_SEQ | ~('\\'|'\'') )* QUOTE;
+fragment UNQUOTEDSTRING
+ : (ESC_SEQ|CHAR)+;
+fragment CHAR
+ : (BASELATIN | DIGIT | ':' | '_');
+
+fragment DIGIT
+ : ('0'..'9');
+
+fragment BASELATIN
+ : ('a'..'z'|'A'..'Z');
+
+fragment
+HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F')
;
+
+fragment
+ESC_SEQ
+ : '\\'
('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
+ | UNICODE_ESC
+ | OCTAL_ESC;
+fragment
+OCTAL_ESC
+ : '\\' ('0'..'3') ('0'..'7')
('0'..'7')
+ | '\\' ('0'..'7') ('0'..'7')
+ | '\\' ('0'..'7');
+fragment
+UNICODE_ESC
+ : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT;
+
+/*for case insensivity*/
+fragment A:('a'|'A');
+fragment B:('b'|'B');
+fragment C:('c'|'C');
+fragment D:('d'|'D');
+fragment E:('e'|'E');
+fragment F:('f'|'F');
+fragment G:('g'|'G');
+fragment H:('h'|'H');
+fragment I:('i'|'I');
+fragment J:('j'|'J');
+fragment K:('k'|'K');
+fragment L:('l'|'L');
+fragment M:('m'|'M');
+fragment N:('n'|'N');
+fragment O:('o'|'O');
+fragment P:('p'|'P');
+fragment Q:('q'|'Q');
+fragment R:('r'|'R');
+fragment S:('s'|'S');
+fragment T:('t'|'T');
+fragment U:('u'|'U');
+fragment V:('v'|'V');
+fragment W:('w'|'W');
+fragment X:('x'|'X');
+fragment Y:('y'|'Y');
+fragment Z:('z'|'Z');
+
+WS : ( ' ' | '\t' | '\r' | '\n')+{$channel=HIDDEN;};
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDWalker.g
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDWalker.g
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/antlr3/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDWalker.g 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,784 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+/*Implementation of compact node type definition tree walker*/
+tree grammar CNDWalker;
+
+/*======================================================*/
+/* HRADER */
+/*======================================================*/
+/* Tree walker options */
+options {
+ ASTLabelType = CommonTree;
+ tokenVocab = CND;
+}
+/* Class header */
+@header{
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.OnParentVersionAction;
+
+import org.antlr.runtime.BaseRecognizer;
+import org.antlr.runtime.BitSet;
+import org.antlr.runtime.DFA;
+import org.antlr.runtime.EarlyExitException;
+import org.antlr.runtime.NoViableAltException;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.RecognizerSharedState;
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.TreeNodeStream;
+import org.antlr.runtime.tree.TreeParser;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import
org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeDataBuilder.NodeDefinitionDataBuilder;
+import
org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeDataBuilder.PropertyDefinitionDataBuilder;
+
+
+}
+/* Class members */
+@members{
+/* registry and location factory objects */
+private NamespaceRegistryImpl namespaceRegistry;
+private LocationFactory locationFactory;
+
+/* It is a list where all namespaces from current stream are placed */
+private List<NameSpace> nameSpaces = new ArrayList<NameSpace>();
+
+/* It is a list where all nodeTypes from current stream are placed */
+private List<NodeTypeData> nodeTypes = new ArrayList<NodeTypeData>();
+
+/* If string is a literal then unQuoteed string is returned */
+public String unQuote(String in){
+ if ((in.length()>=2)&&(in.charAt(0)=='\'')) {
+ in=in.substring(1,in.length()-1);
+ } else if ((in.length()>=2)&&(in.charAt(0)=='\"')){
+ in=in.substring(1,in.length()-1);
+ }
+ return in;
+}
+/*Parsed namespaces are placed here*/
+public List<NameSpace> getNameSpaces() {
+ return nameSpaces;
+}
+/*Parsed nodeTypes are placed here*/
+public List<NodeTypeData> getNodeTypes() {
+ return nodeTypes;
+}
+/* Extend RecognitionException adding desired constructors */
+class TreeWalkerException extends RecognitionException {
+
+ private String message;
+ private Throwable cause;
+
+ public TreeWalkerException(String message, Throwable cause) {
+ this.message = message;
+ this.cause = cause;
+ }
+
+ public TreeWalkerException(String message) {
+ this.message = message;
+ }
+
+ public Throwable getCause() {
+ return (cause == this ? null : cause);
+ }
+
+ public String getMessage() {
+ return message;
+ }
+ }
+/*Class containing namespace definition*/
+class NameSpace{
+ private String prefix;
+ private String uri;
+ public NameSpace() {
+ super();
+ }
+
+ public NameSpace(String prefix, String uri) {
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+ public String getPrefix() {
+ return prefix;
+ }
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+ public String getUri() {
+ return uri;
+ }
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+ public String toString(){
+ return "<"+prefix+"='"+uri+"'>";
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ NameSpace other = (NameSpace) obj;
+ if (!this.uri.equalsIgnoreCase(other.uri)){
+ return false;
+ }
+ if (this.prefix.compareTo(other.prefix)!=0){
+ return false;
+ }
+ return true;
+ }
+}
+/*method for converting from string to InternalQName*/
+private InternalQName toName(String name) throws RecognitionException{
+ try {
+ return locationFactory.parseJCRName(name).getInternalName();
+ } catch (RepositoryException e) {
+ throw new TreeWalkerException(e.getMessage(), e);
+ }
+}
+}
+
+/* Main method. Parameter is an instance of NamespaceRegistryImpl to have
+ * an ability of registering namespaces and parsing strings to InternalQNames */
+cnd [NamespaceRegistryImpl namespaceRegistryImpl]
+ @init {
+ this.namespaceRegistry = namespaceRegistryImpl;
+ this.locationFactory = new LocationFactory(namespaceRegistry);
+ }
+ : (namespace|nodetypedef)*;
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*==================== NAMESPACES ======================*/
+/* Namespace definition rule */
+namespace
+ scope {
+ NameSpace ns; /*local for evry namespace variable*/
+ }
+ @init {
+ $namespace::ns = new NameSpace();
+ }
+ @after {
+ nameSpaces.add($namespace::ns);/*Adding to global list*/
+ if (!namespaceRegistry.isUriRegistered($namespace::ns.getUri())){
+ namespaceRegistry.registerNamespace($namespace::ns.getPrefix(),
$namespace::ns.getUri());
+ } else if
(!namespaceRegistry.getPrefix($namespace::ns.getUri()).equals($namespace::ns.getPrefix()))
+ {
+ namespaceRegistry.registerNamespace($namespace::ns.getPrefix(),
$namespace::ns.getUri());
+ }
+ }
+
+ : ^(NAMESPACE prefix uri);
+
+ catch[RepositoryException e]{
+ throw new TreeWalkerException(e.getMessage(), e);
+ }
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+prefix
+ : ^(PREFIX name)
+ {
+ $namespace::ns.setPrefix(unQuote($name.text));
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+uri
+ : ^(URI STRING)
+ {
+ $namespace::ns.setUri(unQuote($STRING.text));
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+/*==================== NODETYPES ======================*/
+/*NODETYPE DEFINITION*/
+nodetypedef
+ scope {
+ /*local for every nodetypedef loop variable*/
+ NodeTypeDataBuilder nodeTypeBuilder;
+ }
+ @init {
+ $nodetypedef::nodeTypeBuilder= new NodeTypeDataBuilder();
+ }
+ @after {
+ /* Add new NodeType after NodeTypeDataBuilder is filled up */
+ nodeTypes.add($nodetypedef::nodeTypeBuilder.build());
+ }
+
+ : ^(NODETYPEDEF nodetypename supertypes? nodetypeattributes? propertydef* childnodedef*)
;
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*NODE TYPE DEFINITION PARTS*/
+nodetypename
+ : ^(NODETYPENAME name)
+ {
+ $nodetypedef::nodeTypeBuilder.setName(toName($name.text));
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*NODE TYPE SUPERTYPES*/
+supertypes
+
+ : {
+ List<InternalQName> l = new ArrayList<InternalQName>();
+ }
+
+ ^(SUPERTYPES (n=name{l.add(toName($n.text));})+)
+
+ {
+ InternalQName[] list = new InternalQName[l.size()];
+ l.toArray(list);
+ $nodetypedef::nodeTypeBuilder.setSupertypes(list);
+ }
+
+ | ^(SUPERTYPES VARIANT);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*NODE TYPE ATTRIBUTES*/
+nodetypeattributes
+ : ^(NODETYPEATTRIBUTES nodetypeattribute+);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+nodetypeattribute
+ : opt_orderable
+ | opt_mixin
+ | opt_abstract
+ | opt_noquery
+ | opt_primaryitem;
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*NODETYPE OPTIONS*/
+opt_orderable
+ : ^(ORDERABLE VARIANT?)
+ {
+ $nodetypedef::nodeTypeBuilder.setOrderable(true);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+opt_mixin
+ : ^(MIXIN VARIANT?)
+ {
+ $nodetypedef::nodeTypeBuilder.setMixin(true);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+opt_abstract
+ : ^(ABSTRACT VARIANT?)
+ {
+ $nodetypedef::nodeTypeBuilder.setAbstract(true);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+opt_noquery
+ : ^(NOQUERY VARIANT?)
+ {
+ $nodetypedef::nodeTypeBuilder.setQueryable(false);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+opt_primaryitem
+ : ^(PRIMARYITEM STRING)
+ {
+ $nodetypedef::nodeTypeBuilder.setPrimaryItemName(toName(unQuote($STRING.text)));
+ }
+
+ | ^(PRIMARYITEM VARIANT)
+ {
+ $nodetypedef::nodeTypeBuilder.setPrimaryItemName(null);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*==================== PROPERTIES ======================*/
+/*PROPERTY DEFINITION*/
+propertydef
+ scope {
+ PropertyDefinitionDataBuilder propertyDefinitionBuilder;
+ }
+ @init {
+ $propertydef::propertyDefinitionBuilder
=$nodetypedef::nodeTypeBuilder.newPropertyDefinitionDataBuilder();
+ }
+ : ^(PROPERTYDEF propertyname propertytype? propertyparams*);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*PROPERTY PARAMETERS*/
+propertyparams
+ : {
+ List<String> l = new ArrayList<String>();
+ }
+
+ ^(DEFAULTVALUES (s=STRING{l.add(unQuote($s.text));})+)
+
+ {
+ String[] list = new String[l.size()];
+ l.toArray(list);
+ $propertydef::propertyDefinitionBuilder.setDefaultValues(list);
+ }
+
+
+ | ^(DEFAULTVALUES VARIANT)
+ /* Do nothing in this case */
+ | ^(PROPERTYATTRIBUTE propertyattribute)
+ /* Do nothing in this case */
+ | {
+ List<String> l = new ArrayList<String>();
+ }
+
+ ^(VALUECONSTRAINTS (s=STRING{l.add(unQuote($s.text));})+)
+
+ {
+ String[] list = new String[l.size()];
+ l.toArray(list);
+ $propertydef::propertyDefinitionBuilder.setValueConstraints(list);
+ }
+
+ | ^(VALUECONSTRAINTS VARIANT)
+ {
+ /*do nothing!*/
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+propertyname
+ : ^(PROPERTYNAME pn=name)
+ {
+ $propertydef::propertyDefinitionBuilder.setName(toName($name.text));
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+propertytype
+ : ^(PROPERTYTYPE propertytypes)
+ {
+ $propertydef::propertyDefinitionBuilder.setRequiredType($propertytypes.type);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+propertytypes returns [int type]
+ : PT_STRING
+ {
+ type = PropertyType.STRING;
+ }
+ | PT_BINARY
+ {
+ type = PropertyType.BINARY;
+ }
+ | PT_LONG
+ {
+ type = PropertyType.LONG;
+ }
+ | PT_DOUBLE
+ {
+ type = PropertyType.DOUBLE;
+ }
+ | PT_BOOLEAN
+ {
+ type = PropertyType.BOOLEAN;
+ }
+ | PT_DATE
+ {
+ type = PropertyType.DATE;
+ }
+ | PT_NAME
+ {
+ type = PropertyType.NAME;
+ }
+ | PT_PATH
+ {
+ type = PropertyType.PATH;
+ }
+ | PT_REFERENCE
+ {
+ type = PropertyType.REFERENCE;
+ }
+ | PT_WEAKREFERENCE
+ {
+ type = PropertyType.UNDEFINED;
+ }
+ | PT_DECIMAL
+ {
+ type = PropertyType.UNDEFINED;
+ }
+ | PT_URI
+ {
+ type = PropertyType.UNDEFINED;
+ }
+ | PT_UNDEFINED
+ {
+ type = PropertyType.UNDEFINED;
+ }
+ | VARIANT
+ {
+ type = PropertyType.STRING;
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+propertyattribute
+ : atr_autocreated
+ {
+ $propertydef::propertyDefinitionBuilder.setAutoCreated(true);
+ }
+ | atr_mandatory
+ {
+ $propertydef::propertyDefinitionBuilder.setMandatory(true);
+ }
+ | atr_protected
+ {
+ $propertydef::propertyDefinitionBuilder.setProtected(true);
+ }
+ | atr_OPV
+ {
+ $propertydef::propertyDefinitionBuilder.setOnParentVersion($atr_OPV.action);
+ }
+ | atr_multiple
+ {
+ $propertydef::propertyDefinitionBuilder.setMultiple(true);
+ }
+ | atr_queryops
+ {
+ $propertydef::propertyDefinitionBuilder.setQueryOperators($atr_queryops.list);
+ }
+ | atr_nofulltext
+ {
+ $propertydef::propertyDefinitionBuilder.setFullTextSearchable(false);
+ }
+ | atr_noqueryorder
+ {
+ $propertydef::propertyDefinitionBuilder.setQueryOrderable(false);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*PROPERTY ATTRIBUTES*/
+atr_autocreated
+ : ^(AUTOCREATED VARIANT?);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+atr_mandatory
+ : ^(MANDATORY VARIANT?);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+atr_protected
+ : ^(PROTECTED VARIANT?);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+atr_OPV returns [int action]
+ : ^(OPV T_OPV)
+ {
+ action = OnParentVersionAction.valueFromName($T_OPV.text.toUpperCase());
+ }
+
+ | ^(OPV VARIANT)
+ {
+ action = OnParentVersionAction.COPY;
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+atr_multiple
+ : ^(MULTIPLE VARIANT?);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+atr_queryops returns [String[\] list]
+ : ^(QUERYOPS operators)
+ {
+ list=$operators.list;
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*Operators*/
+operators returns [String[\] list]
+ : o=STRING
+ {
+ String opString = $o.text;
+ opString=unQuote(opString.toUpperCase());
+ String[] ops = opString.split(",");
+ List<String> queryOps = new LinkedList<String>();
+ for (String op : ops) {
+ String s = op.trim();
+ if (!Pattern.matches("(<=)|(>=)|(<)|(>)|(=)|(<>)|(LIKE)",
s)){
+ throw new TreeWalkerException("Wrong operator:"+s);
+ }
+ queryOps.add(s);
+ }
+ list=queryOps.toArray(new String[queryOps.size()]);
+ }
+
+ | '?'
+ {
+ //list = Operator.getAllQueryOperators();
+ list = new String[0];
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+atr_nofulltext
+ : ^(NOFULLTEXT VARIANT?);
+ catch[RecognitionException e]{
+ throw e;
+ }
+atr_noqueryorder
+ : ^(NOQUERYORDER VARIANT?);
+ catch[RecognitionException e]{
+ throw e;
+ }
+atr_sns
+ : ^(SNS VARIANT?);
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*==================== CHILDREN ======================*/
+/*CHILD NODE DEFINITION*/
+childnodedef
+ scope {
+ NodeDefinitionDataBuilder childDefinitionBuilder;
+ }
+ @init {
+ $childnodedef::childDefinitionBuilder =
$nodetypedef::nodeTypeBuilder.newNodeDefinitionDataBuilder();
+ }
+ : ^(CHILDDEF nodename requiredtypes? defaulttype? nodeattributes*);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+nodename
+ : ^(NODENAME name)
+ {
+ $childnodedef::childDefinitionBuilder.setName(toName($name.text));
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+requiredtypes
+ : {
+ List<InternalQName> l = new ArrayList<InternalQName>();
+ }
+ ^(REQUIREDTYPES (n=name{l.add(toName($n.text));})+)
+
+ {
+ InternalQName[] list = new InternalQName[l.size()];
+ l.toArray(list);
+ $childnodedef::childDefinitionBuilder.setRequiredPrimaryTypes(list);
+ }
+
+ | ^(REQUIREDTYPES VARIANT);
+ /* Do nothing in this case */
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+defaulttype
+ : ^(DEFAULTTYPE name)
+ {
+ $childnodedef::childDefinitionBuilder.setDefaultPrimaryType(toName($name.text));
+ }
+ | ^(DEFAULTTYPE VARIANT);
+ /* Do nothing in this case */
+
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+nodeattributes
+ : ^(NODEATTRIBUTE nodeattribute);
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+nodeattribute
+ : atr_autocreated
+ {
+ $childnodedef::childDefinitionBuilder.setAutoCreated(true);
+ }
+ | atr_mandatory
+ {
+ $childnodedef::childDefinitionBuilder.setMandatory(true);
+ }
+ | atr_protected
+ {
+ $childnodedef::childDefinitionBuilder.setProtected(true);
+ }
+ | atr_OPV
+ {
+ $childnodedef::childDefinitionBuilder.setOnParentVersion($atr_OPV.action);
+ }
+ | atr_sns
+ {
+ $childnodedef::childDefinitionBuilder.setAllowsSameNameSiblings(true);
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+
+/*==================== GENERAL RULES ======================*/
+/* name is a string that can be the same as registered words */
+name returns [String text]
+ : STRING
+ {
+ text = unQuote($STRING.text);
+ }
+ | registeredWords
+ {
+ text = $registeredWords.text;
+ };
+
+ catch[RecognitionException e]{
+ throw e;
+ }
+/* List of registred words */
+registeredWords returns [String text]
+ : v=T_ORDERABLE {text=$v.getText();}
+ | v=T_ORD {text=$v.getText();}
+ | v=T_O {text=$v.getText();}
+ | v=T_MIXIN {text=$v.getText();}
+ | v=T_MIX {text=$v.getText();}
+ | v=T_M {text=$v.getText();}
+ | v=T_ABSTRACT {text=$v.getText();}
+ | v=T_ABS {text=$v.getText();}
+ | v=T_A {text=$v.getText();}
+ | v=T_NOQUERY {text=$v.getText();}
+ | v=T_NQ {text=$v.getText();}
+ | v=T_AUTOCREATED {text=$v.getText();}
+ | v=T_AUT {text=$v.getText();}
+ | v=T_MANDATORY {text=$v.getText();}
+ | v=T_MAN {text=$v.getText();}
+ | v=T_PROTECTED {text=$v.getText();}
+ | v=T_PRO {text=$v.getText();}
+ | v=T_P {text=$v.getText();}
+ | v=T_OPV {text=$v.getText();}
+ | v=T_OPV_OPV {text=$v.getText();}
+ | v=T_PRIMARY {text=$v.getText();}
+ | v=T_MULTIPLE {text=$v.getText();}
+ | v=T_MUL {text=$v.getText();}
+ | v=T_QUERYOPS {text=$v.getText();}
+ | v=T_QOP {text=$v.getText();}
+ | v=T_NOFULLTEXT {text=$v.getText();}
+ | v=T_NOF {text=$v.getText();}
+ | v=T_NOQUERYORDER {text=$v.getText();}
+ | v=T_NQORD {text=$v.getText();}
+ | v=T_SNS {text=$v.getText();}
+ | v=PT_STRING {text=$v.getText();}
+ | v=PT_BINARY {text=$v.getText();}
+ | v=PT_LONG {text=$v.getText();}
+ | v=PT_DOUBLE {text=$v.getText();}
+ | v=PT_BOOLEAN {text=$v.getText();}
+ | v=PT_DATE {text=$v.getText();}
+ | v=PT_NAME {text=$v.getText();}
+ | v=PT_PATH {text=$v.getText();}
+ | v=PT_REFERENCE {text=$v.getText();}
+ | v=PT_WEAKREFERENCE {text=$v.getText();}
+ | v=PT_DECIMAL {text=$v.getText();}
+ | v=PT_URI {text=$v.getText();}
+ | v=PT_UNDEFINED {text=$v.getText();};
+
+ catch[RecognitionException e]{
+ throw e;
+ }
Modified:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java 2012-02-01
12:19:28 UTC (rev 5551)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -40,6 +40,8 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import
org.exoplatform.services.jcr.impl.core.nodetype.registration.CNDNodeTypeDataPersister;
import
org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeDefinitionComparator;
import org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeConverter;
import
org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeDataPersister;
@@ -622,7 +624,7 @@
}
else if (contentType.equalsIgnoreCase(TEXT_X_JCR_CND))
{
- throw new RepositoryException("Unsupported content type:" +
contentType);
+ serializer = new CNDNodeTypeDataPersister(is,
(NamespaceRegistryImpl)namespaceRegistry);
}
else
{
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDNodeTypeDataPersister.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDNodeTypeDataPersister.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDNodeTypeDataPersister.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:Sergey.Kabashnyuk@gmail.com">Sergey
Kabashnyuk</a>
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay
Zamosenchuk</a>
+ * @version $Id: $
+ */
+public class CNDNodeTypeDataPersister implements NodeTypeDataPersister
+{
+ /**
+ * Class logger.
+ */
+ private final Log log = ExoLogger.getLogger(CNDNodeTypeDataPersister.class);
+
+ private final InputStream is;
+
+ private final OutputStream os;
+
+ private final NamespaceRegistryImpl namespaceRegistry;
+
+ /**
+ * {@inheritDoc}
+ */
+ public CNDNodeTypeDataPersister(InputStream is, OutputStream os, NamespaceRegistryImpl
namespaceRegistry)
+ {
+ super();
+ this.is = is;
+ this.os = os;
+ this.namespaceRegistry = namespaceRegistry;
+ }
+
+ public CNDNodeTypeDataPersister(OutputStream os, NamespaceRegistryImpl
namespaceRegistry)
+ {
+ this(null, os, namespaceRegistry);
+ }
+
+ public CNDNodeTypeDataPersister(InputStream is, NamespaceRegistryImpl
namespaceRegistry)
+ {
+ this(is, null, namespaceRegistry);
+ }
+
+ public CNDNodeTypeDataPersister(OutputStream os)
+ {
+ this(null, os, new NamespaceRegistryImpl());
+ }
+
+ public CNDNodeTypeDataPersister(InputStream is)
+ {
+ this(is, null, new NamespaceRegistryImpl());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addNodeType(NodeTypeData nodeType) throws RepositoryException
+ {
+ throw new UnsupportedRepositoryOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNodeType(InternalQName nodeTypeName) throws RepositoryException
+ {
+ throw new UnsupportedRepositoryOperationException();
+ }
+
+ public boolean isStorageFilled()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IOException
+ */
+ public void addNodeTypes(List<NodeTypeData> nodeTypes) throws
RepositoryException
+ {
+ new CNDStreamWriter(namespaceRegistry).write(nodeTypes, os);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeNodeType(NodeTypeData nodeType) throws RepositoryException
+ {
+ throw new UnsupportedRepositoryOperationException();
+ }
+
+ public void start()
+ {
+ }
+
+ public void stop()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<NodeTypeData> getAllNodeTypes() throws RepositoryException
+ {
+ return new CNDStreamReader(namespaceRegistry).read(is);
+ }
+
+ public void update(List<NodeTypeData> nodeTypes, UpdateNodeTypeObserver
observer) throws RepositoryException
+ {
+ throw new UnsupportedRepositoryOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see
org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeTypeDataPersister#getNodeType(org.exoplatform.services.jcr.datamodel.InternalQName)
+ */
+ public NodeTypeData getNodeType(InternalQName nodeTypeName) throws
RepositoryException
+ {
+ return null;
+ }
+
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamReader.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamReader.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamReader.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import org.antlr.runtime.ANTLRInputStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.tree.CommonTreeNodeStream;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.<br>
+ * Class provides CND grammar manipulation tool for reading node type
+ * definitions and namespaces from stream.
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay
Zamosenchuk</a>
+ * @version $Id: $
+ */
+public class CNDStreamReader
+{
+
+ /**
+ * RegistryImpl instance
+ */
+ private NamespaceRegistryImpl namespaceRegistry;
+
+ /**
+ * Constructs instance of CNDStreamReader. Instance of NamespaceRegistryImpl
+ * is used to parse strings as InternalQnames.
+ *
+ * @param namespaceRegistry
+ */
+ public CNDStreamReader(NamespaceRegistryImpl namespaceRegistry)
+ {
+ this.namespaceRegistry = namespaceRegistry;
+ }
+
+ /**
+ * Method which reads input stream as compact node type definition string. If
+ * any namespaces are placed in stream they are registered through namespace
+ * registry.
+ *
+ * @param is {@link InputStream} to read from.
+ * @return List of parsed nodetypes
+ * @throws RepositoryException Exception is thrown when wrong input is
+ * provided in stream or any {@link IOException} are repacked to
+ * {@link RepositoryException}
+ */
+ public List<NodeTypeData> read(InputStream is) throws RepositoryException
+ {
+ try
+ {
+ if (is != null)
+ {
+ /** Lexing input stream */
+ CNDLexer lex = new CNDLexer(new ANTLRInputStream(is));
+ CommonTokenStream tokens = new CommonTokenStream(lex);
+ /** Parsing input stream */
+ CNDParser parser = new CNDParser(tokens);
+ CNDParser.cnd_return r;
+ /** Throw exception if any lex errors found */
+ if (lex.hasError())
+ {
+ throw new RepositoryException("Lexer errors found " +
lex.getErrors().toString());
+ }
+ r = parser.cnd();
+ /** Throw exception if any parse errors found */
+ if (parser.hasError())
+ {
+ throw new RepositoryException("Parser errors found " +
parser.getErrors().toString());
+ }
+ CommonTreeNodeStream nodes = new CommonTreeNodeStream(r.getTree());
+ CNDWalker walker = new CNDWalker(nodes);
+ /**
+ * Running tree walker to build nodetypes. Namespace registry is
+ * provided to register namespaced mentioned in stream and
+ * locationFactory is used to parse JCR names
+ */
+ walker.cnd(namespaceRegistry);
+ return walker.getNodeTypes();
+ }
+ else
+ {
+ return new ArrayList<NodeTypeData>();
+ }
+
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e.getMessage(), e);
+ }
+ catch (RecognitionException e)
+ {
+ throw new RepositoryException(e.getMessage(), e);
+ }
+ }
+
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamWriter.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamWriter.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/CNDStreamWriter.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.nodetype.registration;
+
+import org.exoplatform.services.jcr.core.ExtendedPropertyType;
+import org.exoplatform.services.jcr.core.nodetype.NodeDefinitionData;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.core.nodetype.PropertyDefinitionData;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.version.OnParentVersionAction;
+
+/**
+ * Created by The eXo Platform SAS.<br>
+ * Class provides CND grammar manipulation tool for writing list of node types
+ * and concomitant namespaces to stream in CDN text format.
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay
Zamosenchuk</a>
+ * @version $Id: $
+ */
+public class CNDStreamWriter
+{
+
+ /**
+ * RegistryImpl instance
+ */
+ private final NamespaceRegistryImpl namespaceRegistry;
+
+ /**
+ * Location factory instance
+ */
+ private final LocationFactory locationFactory;
+
+ /**
+ * Constructs instance of CNDStreamWriter. Instance of NamespaceRegistryImpl
+ * is used to convert InternalQnames to strings.
+ *
+ * @param namespaceRegistry
+ */
+ public CNDStreamWriter(NamespaceRegistryImpl namespaceRegistry)
+ {
+ this.namespaceRegistry = namespaceRegistry;
+ this.locationFactory = new LocationFactory(namespaceRegistry);
+ }
+
+ /**
+ * Write given list of node types to output stream.
+ *
+ * @param nodeTypes
+ * List of NodeTypes to write.
+ * @param os
+ * OutputStream to write to.
+ * @throws RepositoryException
+ */
+ public void write(List<NodeTypeData> nodeTypes, OutputStream os) throws
RepositoryException
+ {
+ OutputStreamWriter out = new OutputStreamWriter(os);
+ try
+ {
+ for (NodeTypeData nodeType : nodeTypes)
+ {
+ printNamespaces(nodeType, out);
+ printNodeTypeDeclaration(nodeType, out);
+ }
+ out.close();
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e.getMessage(), e);
+ }
+
+ }
+
+ /**
+ * Print namespaces to stream
+ *
+ * @param nodeTypeData
+ * @param out
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ private void printNamespaces(NodeTypeData nodeTypeData, OutputStreamWriter out) throws
RepositoryException,
+ IOException
+ {
+
+ /**
+ * Using set to store all prefixes found in node types to avoid
+ * duplication
+ */
+ Set<String> namespaces = new HashSet<String>();
+ /** Scanning nodeType definition for used namespaces */
+ printNameNamespace(nodeTypeData.getName(), namespaces);
+ printNameNamespace(nodeTypeData.getPrimaryItemName(), namespaces);
+ if (nodeTypeData.getDeclaredSupertypeNames() != null)
+ {
+ for (InternalQName reqType : nodeTypeData.getDeclaredSupertypeNames())
+ {
+ printNameNamespace(reqType, namespaces);
+ }
+ }
+ /** Scanning property definitions for used namespaces */
+ if (nodeTypeData.getDeclaredPropertyDefinitions() != null)
+ {
+ for (PropertyDefinitionData property :
nodeTypeData.getDeclaredPropertyDefinitions())
+ {
+ printNameNamespace(property.getName(), namespaces);
+ }
+ }
+ /** Scanning child definitions for used namespaces */
+ if (nodeTypeData.getDeclaredChildNodeDefinitions() != null)
+ {
+ for (NodeDefinitionData child : nodeTypeData.getDeclaredChildNodeDefinitions())
+ {
+ printNameNamespace(child.getName(), namespaces);
+ printNameNamespace(child.getDefaultPrimaryType(), namespaces);
+ if (child.getRequiredPrimaryTypes() != null)
+ {
+ for (InternalQName reqType : child.getRequiredPrimaryTypes())
+ {
+ printNameNamespace(reqType, namespaces);
+ }
+ }
+ }
+ }
+ for (String prefix : namespaces)
+ {
+ String uri = namespaceRegistry.getURI(prefix);
+ out.write("<" + prefix + "='" + uri +
"'>\r\n");
+ }
+ }
+
+ private void printNameNamespace(InternalQName name, Set<String> namespaces)
throws RepositoryException
+ {
+ /** Adding current name's prefix to set if it is not default */
+ if (name != null)
+ {
+ String prefix = locationFactory.createJCRName(name).getPrefix();
+ if (!namespaceRegistry.isDefaultPrefix(prefix))
+ {
+ namespaces.add(prefix);
+ }
+ }
+ }
+
+ /**
+ * Method recursively print to output stream node type definition in cnd
+ * format.
+ *
+ * @param nodeTypeData
+ * is nodeType to print
+ * @throws RepositoryException
+ * this exception may be while converting QNames to string
+ * @throws IOException
+ * this exception my be thrown during some operations with streams
+ */
+ private void printNodeTypeDeclaration(NodeTypeData nodeTypeData, OutputStreamWriter
out) throws RepositoryException,
+ IOException
+ {
+
+ /** Print name */
+ out.write("[" + qNameToString(nodeTypeData.getName()) + "] ");
+ /** Print supertypes */
+ InternalQName[] superTypes = nodeTypeData.getDeclaredSupertypeNames();
+ if (superTypes != null && superTypes.length > 0)
+ {
+ /** if there is only 1 element and it is NT_BASE then avoid printing it */
+ if (superTypes.length > 1 || !superTypes[0].equals(Constants.NT_BASE))
+ {
+ out.write("> " + qNameToString(superTypes[0]));
+ for (int i = 1; i < superTypes.length; i++)
+ {
+ out.write(", " + qNameToString(superTypes[i]));
+ }
+ }
+ }
+
+ /** Print attributes */
+ StringBuffer attributes = new StringBuffer();
+ // if (nodeTypeData.isAbstract())
+ // {
+ // attributes += "abstract ";
+ // }
+ if (nodeTypeData.hasOrderableChildNodes())
+ {
+ attributes.append("orderable ");
+ }
+ if (nodeTypeData.isMixin())
+ {
+ attributes.append("mixin ");
+ }
+ // if (!nodeTypeData.isQueryable())
+ // {
+ // attributes += "noquery ";
+ // }
+ if (nodeTypeData.getPrimaryItemName() != null)
+ {
+ attributes.append("primaryitem " +
qNameToString(nodeTypeData.getPrimaryItemName()));
+ }
+ if (attributes.length() > 0)
+ {
+ out.write("\r\n ");
+ out.write(attributes.toString());
+ }
+ /** Print all property definitions */
+ PropertyDefinitionData[] propertyDefinitions =
nodeTypeData.getDeclaredPropertyDefinitions();
+ if (propertyDefinitions != null)
+ {
+ for (PropertyDefinitionData propertyDefinition : propertyDefinitions)
+ {
+ printPropertyDeclaration(propertyDefinition, out);
+ }
+ }
+ /** Print all child definitions */
+ NodeDefinitionData[] nodeDefinitions =
nodeTypeData.getDeclaredChildNodeDefinitions();
+ if (nodeDefinitions != null)
+ {
+ for (NodeDefinitionData nodeDefinition : nodeDefinitions)
+ {
+ printChildDeclaration(nodeDefinition, out);
+ }
+ }
+
+ out.write("\r\n");
+ }
+
+ /**
+ * Prints to output stream property definition in CND format
+ *
+ * @param propertyDefinition
+ * @throws IOException
+ * @throws RepositoryException
+ */
+ private void printPropertyDeclaration(PropertyDefinitionData propertyDefinition,
OutputStreamWriter out)
+ throws IOException, RepositoryException
+ {
+ /** Print name */
+ out.write("\r\n ");
+ out.write("- " + qNameToString(propertyDefinition.getName()));
+ out.write(" (" +
ExtendedPropertyType.nameFromValue(propertyDefinition.getRequiredType()).toUpperCase() +
")");
+ /** Print default values */
+ out.write(listToString(propertyDefinition.getDefaultValues(), "'",
"\r\n = ", " "));
+
+ /** Print attributes */
+ StringBuffer attributes = new StringBuffer();
+
+ if (propertyDefinition.isAutoCreated())
+ {
+ attributes.append("autocreated ");
+ }
+ if (propertyDefinition.isMandatory())
+ {
+ attributes.append("mandatory ");
+ }
+ if (propertyDefinition.isProtected())
+ {
+ attributes.append("protected ");
+ }
+ if (propertyDefinition.isMultiple())
+ {
+ attributes.append("multiple ");
+ }
+ // if (!propertyDefinition.isFullTextSearchable())
+ // {
+ // attributes += "nofulltext ";
+ // }
+ // if (!propertyDefinition.isQueryOrderable())
+ // {
+ // attributes += "noqueryorder ";
+ // }
+
+ // /** Print operators avoiding printing all */
+ // String[] opArray = propertyDefinition.getAvailableQueryOperators();
+ // /** Using set to avoid duplication */
+ // Set<String> opSet = new HashSet<String>();
+ // for (String op : opArray)
+ // {
+ // opSet.add(op.toUpperCase());
+ // }
+ // /** if not all elements are mentioned in list then print */
+ // if (opSet.size() < 7 && opSet.size() > 0)
+ // {
+ // String opString = opSet.toString();
+ // // opString="queryops '"+opString.substring(1,
opString.length()-1)+"' ";
+ // opString = listToString(opSet.toArray(new String[opSet.size()]),
"", "\r\n queryops '", "' ");
+ // attributes += opString;
+ // }
+
+ if (propertyDefinition.getOnParentVersion() != OnParentVersionAction.COPY)
+ {
+ attributes.append("\r\n " +
OnParentVersionAction.nameFromValue(propertyDefinition.getOnParentVersion()) + "
");
+ }
+ /** Don't print if all attributes are default */
+ if (attributes.length() > 0)
+ {
+ out.write("\r\n ");
+ out.write(attributes.toString());
+ }
+
+ out.write(listToString(propertyDefinition.getValueConstraints(), "'",
"\r\n < ", " "));
+ }
+
+ /**
+ * Print to output stream child node definition in CND format
+ *
+ * @param nodeDefinition
+ * @throws IOException
+ * @throws RepositoryException
+ */
+ private void printChildDeclaration(NodeDefinitionData nodeDefinition,
OutputStreamWriter out) throws IOException,
+ RepositoryException
+ {
+ out.write("\r\n ");
+ out.write("+ " + qNameToString(nodeDefinition.getName()) + "
");
+
+ InternalQName[] requiredTypes = nodeDefinition.getRequiredPrimaryTypes();
+ if (requiredTypes != null && requiredTypes.length > 0)
+ {
+ /** if there is only 1 element and it is NT_BASE then avoid printing it */
+ if (requiredTypes.length > 1 || !requiredTypes[0].equals(Constants.NT_BASE))
+ {
+ out.write("(" + qNameToString(requiredTypes[0]));
+ for (int i = 1; i < requiredTypes.length; i++)
+ {
+ out.write(", " + qNameToString(requiredTypes[i]));
+ }
+ out.write(")");
+ }
+ }
+
+ if (nodeDefinition.getDefaultPrimaryType() != null)
+ {
+ out.write("\r\n = " +
qNameToString(nodeDefinition.getDefaultPrimaryType()));
+ }
+
+ StringBuffer attributes = new StringBuffer();
+
+ if (nodeDefinition.isAutoCreated())
+ {
+ attributes.append("autocreated ");
+ }
+ if (nodeDefinition.isMandatory())
+ {
+ attributes.append("mandatory ");
+ }
+ if (nodeDefinition.isProtected())
+ {
+ attributes.append("protected ");
+ }
+ if (nodeDefinition.isAllowsSameNameSiblings())
+ {
+ attributes.append("sns ");
+ }
+
+ if (nodeDefinition.getOnParentVersion() != OnParentVersionAction.COPY)
+ {
+ attributes.append("\r\n " +
OnParentVersionAction.nameFromValue(nodeDefinition.getOnParentVersion()) + "
");
+ }
+
+ if (attributes.length() > 0)
+ {
+ out.write("\r\n ");
+ out.write(attributes.toString());
+ }
+
+ }
+
+ /**
+ * Converts String[] to String using given notation:
+ * "beforeString+quote+element+quote+',
'+quote+element...+quote+afterString"
+ *
+ * @param list
+ * Array to print
+ * @param quote
+ * Quote string for each element of array
+ * @param beforeString
+ * starting string
+ * @param afterString
+ * ending string
+ * @return
+ */
+ private String listToString(String[] list, String quote, String beforeString, String
afterString)
+ {
+ StringBuffer result = new StringBuffer();
+
+ if (list != null && list.length > 0)
+ {
+ result.append(beforeString);
+ result.append(quote + list[0] + quote);
+ for (int i = 1; i < list.length; i++)
+ {
+ result.append(", " + quote + list[i] + quote);
+ }
+ result.append(afterString);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Converting InternalQName to String, using defined LocationFactory.
+ *
+ * @param name
+ * @return
+ * @throws RepositoryException
+ */
+ private String qNameToString(InternalQName qName) throws RepositoryException
+ {
+ return locationFactory.createJCRName(qName).getAsString();
+ }
+
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.testsuite
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.testsuite
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/test/gunit/org/exoplatform/services/jcr/impl/core/nodetype/registration/CND.testsuite 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+gunit CND;
+
+@header{package org.exoplatform.services.jcr.impl.core.nodetype.registration;}
+//------------------- uri
+uri:
+
+"'http://booblix.net/q.html?q=qw#12'" -> (URI
'http://booblix.net/q.html?q=qw#12')
+
+"'http://booblix.net'" -> (URI 'http://booblix.net')
+
+"'http://booblix.net/q.html?qq=w12'" OK
+
+"'http://192.168.0.2/ns?a=qw&p=%20test'" OK
+
+"http://192.168.0.2/ns?a=qw&p=%20test" FAIL
+
+//------------------- namespace
+namespace:
+
+"<ns = 'http://namespace.com/ns?=3'>" -> (NAMESPACE (PREFIX
ns) (URI 'http://namespace.com/ns?=3'))
+
+"<NS2 =
http://namespace.com/ns?=3>" FAIL
+
+"< NS2 = 'http://namespace.com/ns?=3' >" -> (NAMESPACE
(PREFIX NS2) (URI 'http://namespace.com/ns?=3'))
+
+"< NS2_ = 'http://namespace.com/ns?=3'>" -> (NAMESPACE
(PREFIX NS2_) (URI 'http://namespace.com/ns?=3'))
+
+//------------------- supertypes
+supertypes:
+
+"> ns:ParentType1, ns:parentype2" -> (SUPERTYPES ns:ParentType1
ns:parentype2)
+
+">ns:ParentType1,ns:parentype2" -> (SUPERTYPES ns:ParentType1
ns:parentype2)
+
+"> NS3:P@ar_entType1, ns:parentype2" FAIL
+
+"> NS3:P@ar entType1, ns:parentype2" FAIL
+
+"> NS3:Par_entType1, ns:parentype2" -> (SUPERTYPES NS3:Par_entType1
ns:parentype2)
+
+"> 'NS3:Par entType1', ns:parentype2" -> (SUPERTYPES
'NS3:Par entType1' ns:parentype2)
+
+//------------------- nodetypename
+nodetypename:
+
+"[ns:NodeType]" -> (NODETYPENAME ns:NodeType)
+
+"[ns_:NodeType]" -> (NODETYPENAME ns_:NodeType)
+
+//------------------- nodetypeattributes
+nodetypeattributes:
+
+"abstract orderable mixin primaryitem ex:property" -> (NODETYPEATTRIBUTES
ABSTRACT ORDERABLE MIXIN (PRIMARYITEM ex:property))
+
+"abstract ? orderable mixin primaryitem ex:property" -> (NODETYPEATTRIBUTES
(ABSTRACT ?) ORDERABLE MIXIN (PRIMARYITEM ex:property))
+
+"abstract ? orderable mixin ! ex:property" -> (NODETYPEATTRIBUTES (ABSTRACT
?) ORDERABLE MIXIN (PRIMARYITEM ex:property))
+
+"nq ? orderable mixin ! ex:property" -> (NODETYPEATTRIBUTES (NOQUERY ?)
ORDERABLE MIXIN (PRIMARYITEM ex:property))
+
+"abstract ? orderable m ! ?" -> (NODETYPEATTRIBUTES (ABSTRACT ?) ORDERABLE
MIXIN (PRIMARYITEM ?))
+
+"a ? o m ! ? nq?" -> (NODETYPEATTRIBUTES (ABSTRACT ?) ORDERABLE MIXIN
(PRIMARYITEM ?) (NOQUERY ?))
+
+//------------------- propertyname
+propertyname:
+
+"- exo:Property" -> (PROPERTYNAME exo:Property)
+
+"- exo:Property" -> (PROPERTYNAME exo:Property)
+
+"- exo : Property" FAIL
+
+//------------------- propertytype
+propertytype:
+
+"(STRING)" -> (PROPERTYTYPE STRING)
+
+"(sTriNg)" -> (PROPERTYTYPE sTriNg)
+
+//------------------- opt_orderable
+opt_orderable:
+
+"orderable" OK
+
+"o" OK
+
+"orD" OK
+
+//------------------- opt_mixin
+opt_mixin:
+
+"MixIn" OK
+
+"M" OK
+
+//------------------- opt_abstract
+opt_abstract:
+
+"aBs" OK
+
+//------------------- opt_noquery
+opt_noquery:
+
+"nQ" OK
+
+//------------------- opt_primaryitem
+opt_primaryitem:
+
+"! ns:ItEm" -> (PRIMARYITEM ns:ItEm)
+
+"pRimAryItem ?" OK
+
+//------------------- atr_autocreated
+atr_autocreated:
+
+"a" OK
+
+"aut" OK
+
+//------------------- atr_mandatory
+atr_mandatory:
+
+"m" OK
+
+"Man" OK
+
+//------------------- atr_protected
+atr_protected:
+
+"prO" OK
+
+"p ?" OK
+
+//------------------- atr_OPV
+atr_OPV:
+
+"OPV ?" OK
+
+"oPV?" OK
+
+"VerSion" OK
+
+"COPy ?" FAIL
+
+//------------------- atr_multiple
+atr_multiple:
+
+"muL" OK
+
+"*" OK
+
+"* ?" -> (MULTIPLE ?)
+
+//------------------- atr_queryops
+atr_queryops:
+
+"qOp ?" OK
+
+"QueryOpS '<,=, <>, LikE'" -> (QUERYOPS '<,=,
<>, LikE')
+
+//------------------- atr_nofulltext
+atr_nofulltext:
+
+"nOf" OK
+
+"NOF ?" OK
+
+"noFullText" OK
+
+//------------------- atr_noqueryorder
+atr_noqueryorder:
+
+"nQorD" OK
+
+"NoQueryOrder ?" OK
+
+//------------------- atr_sns
+atr_sns:
+
+"* ?" OK
+
+"SnS" OK
+
+//------------------- valueconstraints
+valueconstraints:
+
+"< 'constr 121' , ' costr 3 '" OK
+
+"< 'asf'" OK
+
+//------------------- requiredtypes
+requiredtypes:
+
+"(ns:type1,ns:type2)" OK
+
+"( ns:ty_pe1 , ns:type2 )" OK
+
+"(ns:t@ype1,ns:type2)" FAIL
+
+"(ns:type1 , ns:type2 , )" FAIL
+
+//------------------- cnd
+cnd:
+
+"<ns = 'http://namespace.com/ns'> [ns:NodeType] >
ns:ParentType1, ns:ParentType2 abstract orderable mixin noquery primaryitem
ex:property - ex:property (STRING) = 'default1', 'default2'
mandatory autocreated protected multiple VERSION < 'constraint1',
'constraint2' queryops '=, <>, <, <=, >, >=, LIKE'
nofulltext noqueryorder + ns:node (ns:reqType1, ns:reqType2) = ns:defaultType
mandatory autocreated protected sns VERSION" OK
+
+//------------------- prefix
+prefix:
+
+"prefix" OK
+
+"prefix::" OK
+
+"_pref" OK
+
+"COPY" OK
+
+"MIXIN" OK
+
+"m" OK
+
+//------------------- propertyattributes
+propertyattributes:
+
+"sns" FAIL
+
+"* ?" OK
+
+//------------------- nodename
+nodename:
+
+"+ node" -> (NODENAME node)
+
+//------------------- defaulttype
+defaulttype:
+
+"= ns:deftype" OK
+
+"= ntype, type" FAIL
+
+"= ns:type" -> (DEFAULTTYPE ns:type)
+
+//------------------- nodeattributes
+nodeattributes:
+
+"aut" OK
+
+"m" OK
+
+"mul" FAIL
+
+//------------------- name
+name:
+
+"*" FAIL
+
+"copy" OK
+
+"m" OK
+
+"!" FAIL
+
+"undefined" OK
+
+"opv" OK
+
+"opv?" FAIL
+
+//------------------- propertydef
+propertydef:
+
+"- preF:propName (string) = 'string','adfa s as <asf://> ' man
aut * version" -> (PROPERTYDEF (PROPERTYNAME preF:propName) (PROPERTYTYPE string)
(DEFAULTVALUES 'string' 'adfa s as <asf://> ') (PROPERTYATTRIBUTE
MANDATORY) (PROPERTYATTRIBUTE AUTOCREATED) (PROPERTYATTRIBUTE MULTIPLE) (PROPERTYATTRIBUTE
(OPV version)))
+
+//------------------- childnodedef
+childnodedef:
+
+"+ ns:nde ( type1 , string ) = ns:defTypeString mAN aut pro sns opv ?" ->
(CHILDDEF (NODENAME ns:nde) (REQUIREDTYPES type1 string) (DEFAULTTYPE ns:defTypeString)
(NODEATTRIBUTE MANDATORY) (NODEATTRIBUTE AUTOCREATED) (NODEATTRIBUTE PROTECTED)
(NODEATTRIBUTE SNS) (NODEATTRIBUTE (OPV VARIANT)))
\ No newline at end of file
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDNodeTypeRegistration.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDNodeTypeRegistration.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDNodeTypeRegistration.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.exoplatform.services.jcr.impl.core.nodetype;
+
+import org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+/**
+ * Test node types with binary default values.
+ */
+public class TestCNDNodeTypeRegistration extends AbstractNodeTypeTest
+{
+
+ /**
+ * Test a node type with a binary default value
+ * @throws RepositoryException
+ */
+ public void testNodeTypesWithBinaryDefaultValue() throws RepositoryException,
IOException
+ {
+ doTestNodeTypesWithBinaryDefaultValue(0);
+ doTestNodeTypesWithBinaryDefaultValue(10);
+ doTestNodeTypesWithBinaryDefaultValue(10000);
+ }
+
+ public void doTestNodeTypesWithBinaryDefaultValue(int len) throws RepositoryException,
IOException
+ {
+ char[] chars = new char[len];
+ for (int i = 0; i < chars.length; i++)
+ {
+ chars[i] = 'a';
+ }
+ String def = new String(chars);
+
+ String type = "nodetypeTest:foo" + len;
+ String cnd =
+
"<nodetypeTest='http://www.exoplatform.com/jcr/exo/1.0/test/nodetype'>\n"
+ "[" + type
+ + "]\n - value(binary) = '" + def + "' m a";
+
+ InputStream cndStream = new ByteArrayInputStream(cnd.getBytes("UTF-8"));
+ nodeTypeManager.registerNodeTypes(cndStream,
ExtendedNodeTypeManager.FAIL_IF_EXISTS,
+ NodeTypeDataManager.TEXT_X_JCR_CND);
+
+ Node node = root.addNode("testfoo" + len, type);
+ Value value = node.getProperty("value").getValue();
+ assertEquals(PropertyType.BINARY, value.getType());
+ assertEquals(def, value.getString());
+ }
+
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDParser.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDParser.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDParser.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,511 @@
+package org.exoplatform.services.jcr.impl.core.nodetype;
+
+import org.exoplatform.services.jcr.core.nodetype.NodeDefinitionData;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.core.nodetype.PropertyDefinitionData;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import org.exoplatform.services.jcr.impl.core.nodetype.registration.CNDStreamReader;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.OnParentVersionAction;
+
+/**
+ * Created by The eXo Platform SAS. This class provides set of test for CND
+ * grammar parser implementation
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay
Zamosenchuk</a>
+ * @version $Id: $
+ */
+public class TestCNDParser extends AbstractNodeTypeTest
+{
+
+ private final NamespaceRegistryImpl namespaceRegistry = new NamespaceRegistryImpl();
+
+ private final LocationFactory locationFactory = new
LocationFactory(namespaceRegistry);
+
+ private InternalQName toName(String name) throws RepositoryException
+ {
+ return locationFactory.parseJCRName(name).getInternalName();
+ }
+
+ /**
+ * Runs {@link CNDStreamReader} with std.err and std.out redirecting to avoid
+ * parse errors output
+ *
+ * @param line
+ * String containing node types in compact node type format
+ * @return list of {@link NodeTypeData}
+ * @throws RepositoryException
+ */
+ private List<NodeTypeData> parseString(String line) throws RepositoryException
+ {
+ /**
+ * Start of I/O Redirecting. gUnit test uses std.err and std.out to
+ * examine the result of running test. So in ordinary situation parse
+ * errors are printed in std.err. In this case std devices are replaced by
+ * stubs
+ */
+ PrintStream console = System.out;
+ PrintStream consoleErr = System.err;
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(out);
+ PrintStream ps2 = new PrintStream(err);
+ System.setOut(ps);
+ System.setErr(ps2);
+
+ try
+ {
+ return new CNDStreamReader(namespaceRegistry).read(new
ByteArrayInputStream(line.getBytes()));
+ }
+ finally
+ {
+ System.setOut(console); // Reset standard output
+ System.setErr(consoleErr); // Reset standard err
+ }
+ }
+
+ /**
+ * Testing whether correct default nodeType parameters are assigned
+ */
+ public void testDefaultNodeTypeParameters()
+ {
+
+ try
+ {
+ String ntString = "<ns = 'http://namespace.com/ns'>
[ns:NodeType]";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("ns:NodeType"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), false);
+ assertEquals(ntdActual.hasOrderableChildNodes(), false);
+ //assertEquals(ntdActual.isAbstract(), false);
+ //assertEquals(ntdActual.isQueryable(), true);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{Constants.NT_BASE}));
+ /** Correct properties */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredPropertyDefinitions(), new
PropertyDefinitionData[0]));
+ /** Correct children */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredChildNodeDefinitions(), new
PropertyDefinitionData[0]));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Testing registered words usage
+ */
+ public void testRegisteredWordsUsage1()
+ {
+
+ try
+ {
+ String ntString = "<ns = 'http://namespace.com/ns'>
[ns:COPY]";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("ns:COPY"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), false);
+ assertEquals(ntdActual.hasOrderableChildNodes(), false);
+ //assertEquals(ntdActual.isAbstract(), false);
+ //assertEquals(ntdActual.isQueryable(), true);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{Constants.NT_BASE}));
+ /** Correct properties */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredPropertyDefinitions(), new
PropertyDefinitionData[0]));
+ /** Correct children */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredChildNodeDefinitions(), new
PropertyDefinitionData[0]));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * Testing registered words usage
+ */
+ public void testRegisteredWordsUsage2()
+ {
+
+ try
+ {
+ String ntString =
+ "<opv = 'http://namespace.com/opv'> [opv:STRING] >
opv:decimal, opv:URI abstract orderable mixin noquery";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("opv:STRING"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), true);
+ assertEquals(ntdActual.hasOrderableChildNodes(), true);
+ //assertEquals(ntdActual.isAbstract(), true);
+ //assertEquals(ntdActual.isQueryable(), false);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{toName("opv:decimal"),
+ toName("opv:URI")}));
+ /** Correct properties */
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Testing registered words usage
+ */
+ public void testRegisteredWordsUsage3()
+ {
+
+ try
+ {
+ String ntString =
+ "<opv = 'http://namespace.com/opv'> [opv:mixin] >
opv:decimal, opv:URI abstract orderable mixin noquery";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("opv:mixin"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), true);
+ assertEquals(ntdActual.hasOrderableChildNodes(), true);
+ //assertEquals(ntdActual.isAbstract(), true);
+ //assertEquals(ntdActual.isQueryable(), false);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{toName("opv:decimal"),
+ toName("opv:URI")}));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Testing whether NT:BASE is assigned to nodeType.
+ */
+ public void testBaseTypeAssign()
+ {
+
+ try
+ {
+ String ntString = "<ns = 'http://namespace.com/ns'>
[ns:NodeType] abstract orderable mixin noquery";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("ns:NodeType"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), true);
+ assertEquals(ntdActual.hasOrderableChildNodes(), true);
+ //assertEquals(ntdActual.isAbstract(), true);
+ //assertEquals(ntdActual.isQueryable(), false);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{Constants.NT_BASE}));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * The simplest node type definition is provided to parser. Checking equality
+ * to expected result
+ */
+ public void testSimpleNodeType()
+ {
+
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> [ns:NodeType] >
ns:ParentType1, ns:ParentType2 abstract orderable mixin noquery";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("ns:NodeType"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), null);
+ assertEquals(ntdActual.isMixin(), true);
+ assertEquals(ntdActual.hasOrderableChildNodes(), true);
+ //assertEquals(ntdActual.isAbstract(), true);
+ //assertEquals(ntdActual.isQueryable(), false);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{
+ toName("ns:ParentType1"), toName("ns:ParentType2")}));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Checking if property's default parameters are assigned correctly
+ */
+ public void testDefalultProprtyParameters()
+ {
+
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> <ex =
'http://namespace.com/ex'> [ns:NodeType] > ns:ParentType1, ns:ParentType2 a
o m nq ! ex:property "
+ + "- ex:property";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+ PropertyDefinitionData ptdActual =
ntdActual.getDeclaredPropertyDefinitions()[0];
+
+ assertEquals(ptdActual.getName(), toName("ex:property"));
+ assertEquals(ptdActual.isAutoCreated(), false);
+ assertEquals(ptdActual.isMandatory(), false);
+ assertEquals(ptdActual.getOnParentVersion(), OnParentVersionAction.COPY);
+ assertEquals(ptdActual.isProtected(), false);
+ assertEquals(ptdActual.getRequiredType(), PropertyType.STRING);
+ assertEquals(ptdActual.getValueConstraints(), null);
+ assertEquals(ptdActual.getDefaultValues(), null);
+ assertEquals(ptdActual.isMultiple(), false);
+ // assertEquals(ptdActual.isQueryOrderable(), true);
+ // String[] actual = ptdActual.getAvailableQueryOperators();
+ // String[] expected = Operator.getAllQueryOperators();
+ // Arrays.sort(actual);
+ // Arrays.sort(expected);
+ // assertTrue(Arrays.deepEquals(actual, expected));
+ // assertEquals(ptdActual.isFullTextSearchable(), true);
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Checking if child's default parameters are assigned correctly
+ */
+ public void testDefaultChildParameters()
+ {
+
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> <ex =
'http://namespace.com/ex'> [ns:NodeType] > ns:ParentType1, ns:ParentType2 a
o m nq + ns:node";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+ NodeDefinitionData chdActual = ntdActual.getDeclaredChildNodeDefinitions()[0];
+
+ assertEquals(chdActual.getName(), toName("ns:node"));
+ assertEquals(chdActual.isAutoCreated(), false);
+ assertEquals(chdActual.isMandatory(), false);
+ assertEquals(chdActual.getOnParentVersion(), OnParentVersionAction.COPY);
+ assertEquals(chdActual.isProtected(), false);
+ assertEquals(chdActual.getDefaultPrimaryType(), null);
+ assertEquals(chdActual.isAllowsSameNameSiblings(), false);
+ assertTrue(Arrays.deepEquals(chdActual.getRequiredPrimaryTypes(), new
InternalQName[]{Constants.NT_BASE}));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found " + e.getMessage());
+ }
+ }
+
+ /**
+ * Full nodetype definition is provided to parser. Checking equality to
+ * expected result
+ */
+ public void testComplexNodeType()
+ {
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> <ex =
'http://namespace.com/ex'> [ns:NodeType] > ns:ParentType1, ns:ParentType2 a
o m nq ! ex:property "
+ + "- ex:property (STRING) = 'default1', 'default2'
mandatory aut protected * INITIALIZE "
+ + "< 'constraint1', 'constraint2' queryops '=,
<>, <, <=, >, >=, LIKE' nofulltext noqueryorder "
+ + "+ ns:node (ns:reqType1, ns:reqType2) = ns:defaultType mandatory
autocreated protected sns VERSION "
+ + "+ ns:node2 (ns:reqType1, ns:reqType2, nt:subBase) man p *
VERSION";
+ NodeTypeData ntdActual = parseString(ntString).get(0);
+
+ PropertyDefinitionData ptdActual =
ntdActual.getDeclaredPropertyDefinitions()[0];
+
+ NodeDefinitionData chdActual1 = ntdActual.getDeclaredChildNodeDefinitions()[0];
+ NodeDefinitionData chdActual2 = ntdActual.getDeclaredChildNodeDefinitions()[1];
+
+ /** Correct names */
+ assertEquals(ntdActual.getName(), toName("ns:NodeType"));
+ /** Correct attributes */
+ assertEquals(ntdActual.getPrimaryItemName(), toName("ex:property"));
+ assertEquals(ntdActual.isMixin(), true);
+ assertEquals(ntdActual.hasOrderableChildNodes(), true);
+ // assertEquals(ntdActual.isAbstract(), true);
+ // assertEquals(ntdActual.isQueryable(), false);
+ /** Correct supertypes */
+ assertTrue(Arrays.deepEquals(ntdActual.getDeclaredSupertypeNames(), new
InternalQName[]{
+ toName("ns:ParentType1"), toName("ns:ParentType2")}));
+
+ /** Correct properties */
+ assertEquals(ptdActual.getName(), toName("ex:property"));
+ assertEquals(ptdActual.isAutoCreated(), true);
+ assertEquals(ptdActual.isMandatory(), true);
+ assertEquals(ptdActual.getOnParentVersion(), OnParentVersionAction.INITIALIZE);
+ assertEquals(ptdActual.isProtected(), true);
+ assertEquals(ptdActual.getRequiredType(), PropertyType.STRING);
+ assertTrue(Arrays.deepEquals(ptdActual.getValueConstraints(), new
String[]{"constraint1", "constraint2"}));
+ assertTrue(Arrays.deepEquals(ptdActual.getDefaultValues(), new
String[]{"default1", "default2"}));
+ assertEquals(ptdActual.isMultiple(), true);
+ // assertEquals(ptdActual.isQueryOrderable(), false);
+ // String[] actual = ptdActual.getAvailableQueryOperators();
+ // String[] expected = new String[]{"=", "<>",
"<", "<=", ">", ">=",
"LIKE"};
+ // Arrays.sort(actual);
+ // Arrays.sort(expected);
+ // assertTrue(Arrays.deepEquals(actual, expected));
+ // assertEquals(ptdActual.isFullTextSearchable(), false);
+ /** Correct children */
+ // first child
+ assertEquals(chdActual1.getName(), toName("ns:node"));
+ assertEquals(chdActual1.isAutoCreated(), true);
+ assertEquals(chdActual1.isMandatory(), true);
+ assertEquals(chdActual1.getOnParentVersion(), OnParentVersionAction.VERSION);
+ assertEquals(chdActual1.isProtected(), true);
+ assertEquals(chdActual1.getDefaultPrimaryType(),
toName("ns:defaultType"));
+ assertEquals(chdActual1.isAllowsSameNameSiblings(), true);
+ assertTrue(Arrays.deepEquals(chdActual1.getRequiredPrimaryTypes(), new
InternalQName[]{toName("ns:reqType1"),
+ toName("ns:reqType2")}));
+ // second child
+ assertEquals(chdActual2.getName(), toName("ns:node2"));
+ assertEquals(chdActual2.isAutoCreated(), false);
+ assertEquals(chdActual2.isMandatory(), true);
+ assertEquals(chdActual2.getOnParentVersion(), OnParentVersionAction.VERSION);
+ assertEquals(chdActual2.isProtected(), true);
+ assertEquals(chdActual2.getDefaultPrimaryType(), null);
+ assertEquals(chdActual2.isAllowsSameNameSiblings(), true);
+ assertTrue(Arrays.deepEquals(chdActual2.getRequiredPrimaryTypes(), new
InternalQName[]{toName("ns:reqType1"),
+ toName("ns:reqType2"), toName("nt:subBase")}));
+
+ }
+ catch (RepositoryException e)
+ {
+ fail("Exception found ");
+ }
+
+ }
+
+ /**
+ * Testing whether wrong operator is handled correctly.
+ */
+ public void testWrongOperator()
+ {
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> <ex =
'http://namespace.com/ex'> [ns:NodeType] > ns:ParentType1, ns:ParentType2 a
o m nq ! ex:property - ex:property (STRING) "
+ + "= 'default1', 'default2' mandatory autocreated
protected multiple VERSION < 'constraint1', 'constraint2' "
+ + "queryops '=, <>, <, =>, >, >=, LIKE'
nofulltext noqueryorder";
+ parseString(ntString);
+
+ fail("Exception should be generated! Wrong operator.");
+ }
+ catch (RepositoryException e)
+ {
+ // it's ok!
+ }
+ }
+
+ /**
+ * Testing whether wrong name is handled correctly.
+ */
+ public void testWrongName()
+ {
+ try
+ {
+ String ntString =
+ "<ns = 'http://namespace.com/ns'> [ns::::NodeType] >
ns:ParentType1, ns:ParentType2 a o m nq ! ex:property - ex:property (STRING) "
+ + "= 'default1', 'default2' mandatory autocreated
protected multiple VERSION < 'constraint1', 'constraint2' "
+ + "queryops '=, <>, <, =>, >, >=, LIKE'
nofulltext noqueryorder";
+ parseString(ntString);
+ fail("Exception should be generated! Wrong name.");
+ }
+ catch (RepositoryException e)
+ {
+ // it's ok!
+ }
+ }
+
+ /**
+ * Testing whether wrong input sequence is handled correctly.
+ */
+ public void testWrongInput1()
+ {
+ try
+ {
+ String ntString =
+ "]ns:NodeType[ >< ns:ParentType1, ns:ParentType2 a o m nq !
ex:property - ex:property (STRING) ";
+ parseString(ntString);
+ fail("Exception should be generated! Wrong input.");
+ }
+ catch (RepositoryException e)
+ {
+ // it's ok!
+ }
+ }
+
+ /**
+ * Testing whether wrong input sequence is handled correctly.
+ */
+ public void testWrongInput2()
+ {
+ try
+ {
+ String ntString =
+ "[ns:NodeType] < ns:ParentType1, ns:ParentType2 >a o m nq !
ex:property - ex:property (STRING) ";
+ parseString(ntString);
+ fail("Exception should be generated! Wrong input.");
+ }
+ catch (RepositoryException e)
+ {
+ // it's ok!
+ }
+ }
+
+ /**
+ * Testing whether wrong input sequence is handled correctly.
+ */
+ public void testWrongInput3()
+ {
+ try
+ {
+ String ntString =
+ "[ns:NodeType] > ns:ParentType1, ns:ParentType2 a o =m -nq !
ex:property - ex:property (STRING) ";
+ parseString(ntString);
+ fail("Exception should be generated! Wrong input.");
+ }
+ catch (RepositoryException e)
+ {
+ // it's ok!
+ }
+ }
+
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDSerialization.java
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDSerialization.java
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/core/nodetype/TestCNDSerialization.java 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,57 @@
+package org.exoplatform.services.jcr.impl.core.nodetype;
+
+import org.exoplatform.services.jcr.JcrImplBaseTest;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
+import org.exoplatform.services.jcr.impl.core.nodetype.registration.CNDStreamReader;
+import org.exoplatform.services.jcr.impl.core.nodetype.registration.CNDStreamWriter;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Created by The eXo Platform SAS.<br>
+ * Class that tests read-write-read cycle for compact node type definition tools
+ * ({@link CNDStreamReader} and {@link CNDStreamWriter})
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay
Zamosenchuk</a>
+ * @version $Id: $
+ */
+public class TestCNDSerialization extends JcrImplBaseTest
+{
+
+ private static final String TEST_FILE = "cnd-reader-test-input.cnd";
+
+ public void testSerialization() throws Exception
+ {
+ /** input stream */
+ InputStream is = getClass().getClassLoader().getResourceAsStream("" +
TEST_FILE);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ NamespaceRegistryImpl nsm = new NamespaceRegistryImpl();
+ /** reading and writing */
+ List<NodeTypeData> ntdList1 = new CNDStreamReader(nsm).read(is);
+ new CNDStreamWriter(nsm).write(ntdList1, baos);
+ /** new reader to read previous output */
+ List<NodeTypeData> ntdList2 = new CNDStreamReader(nsm).read(new
ByteArrayInputStream(baos.toByteArray()));
+ /** checking equality */
+ if (ntdList1.size() == 0 || ntdList1.size() != ntdList2.size())
+ {
+ fail("Exported node type definition was not successfully read back
in");
+ }
+ else
+ {
+ for (int k = 0; k < ntdList1.size(); k++)
+ {
+ NodeTypeData ntd1 = ntdList1.get(k);
+ NodeTypeData ntd2 = ntdList2.get(k);
+ if (!ntd1.equals(ntd2))
+ {
+ fail("Exported node type definition was not successfully read back
in. \r\n" + ntd2.getName()
+ + "differs from original " + ntd1.getName() +
"\r\n" + baos.toString());
+ }
+ }
+ }
+ }
+}
Added:
jcr/branches/1.15.x/exo.jcr.component.core/src/test/resources/cnd-reader-test-input.cnd
===================================================================
---
jcr/branches/1.15.x/exo.jcr.component.core/src/test/resources/cnd-reader-test-input.cnd
(rev 0)
+++
jcr/branches/1.15.x/exo.jcr.component.core/src/test/resources/cnd-reader-test-input.cnd 2012-02-01
13:31:49 UTC (rev 5552)
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+<ex = "http://example.org/jackrabbit/example/cnd">
+//<jcr='http://www.jcp.org/jcr/1.0'>
+//<nt='http://www.jcp.org/jcr/nt/1.0'>
+
+// test remapping
+<REP='http://example.org/jackrabbit/example/REP'>
+
+// omit this namespace to test auto-registering
+// <
mix='http://www.jcp.org/jcr/mix/1.0'>
+
+//------------------------------------------------------------------------------
+// E X A M P L E T Y P E S
+//------------------------------------------------------------------------------
+
+[ex:NodeType] > ex:ParentNodeType1, ex:ParentNodeType2
+ orderable mixin
+ - ex:property (long) = '1', '2' mandatory autocreated protected
multiple version < '[1,10]'
+ + ex:node (ex:RequiredNodeType1, ex:RequiredNodeType2) = ex:RequiredNodeType1 mandatory
autocreated protected version
+
+[ex:AnotherNodeType] > ex:NodeType
+ - ex:generic1 (string) = 'a residual property' multiple
+ + ex:generic2 (ex:RequiredNodeType1)
+
+[ex:Empty]
+
+[NoPrefix]
+
+[ex:Reference]
+ - ex:ref (reference) mandatory protected < 'ex:ref'
+
+[ex:Name]
+ - ex:name (name) < 'ex:name'
+
+[ex:Path]
+ - ex:path (path) < 'ex:a/ex:b'
+
+[ex:Full] > ex:NodeType
+ orderable mixin abstract primaryitem ex:p1 noquery
+ - ex:p1 (STRING) mandatory protected autocreated multiple
+ - ex:p2 (BINARY) queryops '=, <>, <, <=, >, >=, LIKE'
+ - ex:p3 (LONG) nofulltext noqueryorder
+ - ex:p4 (DOUBLE)
+ - ex:p5 (BOOLEAN)
+ - ex:p6 (NAME)
+ - ex:p8 (PATH)
+ - ex:p9 (REFERENCE)
+ - ex:pa (WEAKREFERENCE)
+ - ex:pb (DECIMAL)
+ - ex:pc (URI)
+ - ex:pd (UNDEFINED)
+ - ex:pf (*)
+ + ex:n1 (ex:NodeType) COPY
+ + ex:n2 (ex:NodeType) VERSION
+ + ex:n3 (ex:NodeType) INITIALIZE
+ + ex:n4 (ex:NodeType) COMPUTE
+ + ex:n5 (ex:NodeType) IGNORE
+ + ex:n6 (ex:NodeType) ABORT
+
+[ex:Full1] > ex:NodeType
+ orderable mixin abstract primaryitem ex:p1 noquery
+ - ex:p1
+
+//------------------------------------------------------------------------------
+// B A S E T Y P E S
+//------------------------------------------------------------------------------
+
+[nt:base]
+ - jcr:primaryType (name) mandatory autocreated protected compute
+ - jcr:mixinTypes (name) protected multiple compute
+
+[nt:unstructured]
+ orderable
+ - ex:generic1 (undefined) multiple
+ - ex:generic2 (undefined)
+ + ex:generic3 (nt:base) = nt:unstructured version
+
+[mix:referenceable]
+ mixin
+ - jcr:uuid (string) mandatory autocreated protected initialize
+
+[mix:lockable]
+ mixin
+ - jcr:lockOwner (string) protected ignore
+ - jcr:lockIsDeep (boolean) protected ignore
+
+//------------------------------------------------------------------------------
+// V E R S I O N I N G
+//------------------------------------------------------------------------------
+
+[mix:versionable] > mix:referenceable
+ mixin
+ - jcr:versionHistory (reference) mandatory protected
+ < 'nt:versionHistory'
+ - jcr:baseVersion (reference) mandatory protected ignore
+ < 'nt:version'
+ - jcr:isCheckedOut (boolean) = 'true' mandatory autocreated protected ignore
+ - jcr:predecessors (reference) mandatory protected multiple
+ < 'nt:version'
+ - jcr:mergeFailed (reference) protected multiple abort
+
+[nt:versionHistory] > mix:referenceable
+ - jcr:versionableUuid (string) mandatory autocreated protected abort
+ + jcr:rootVersion (nt:version) = nt:version mandatory autocreated protected abort
+ + jcr:versionLabels (nt:versionLabels) = nt:versionLabels mandatory autocreated
protected abort
+ + ex:generic (nt:version) = nt:version protected abort
+
+[nt:versionLabels]
+ - ex:generic (reference) protected abort
+ < 'nt:version'
+
+[nt:version] > mix:referenceable
+ - jcr:created (date) mandatory autocreated protected abort
+ - jcr:predecessors (reference) protected multiple abort
+ < 'nt:version'
+ - jcr:successors (reference) protected multiple abort
+ < 'nt:version'
+ + jcr:frozenNode (nt:frozenNode) protected abort
+
+[nt:frozenNode] > mix:referenceable
+ orderable
+ - jcr:frozenPrimaryType (name) mandatory autocreated protected abort
+ - jcr:frozenMixinTypes (name) protected multiple abort
+ - jcr:frozenUuid (string) mandatory autocreated protected abort
+ - ex:generic1 (undefined) protected abort
+ - ex:generic2 (undefined) protected multiple abort
+ + ex:generic3 (nt:base) protected abort
+
+[nt:versionedChild]
+ - jcr:childVersionHistory (reference) mandatory autocreated protected abort
+ < 'nt:versionHistory'
+
+//------------------------------------------------------------------------------
+// N O D E T Y P E S
+//------------------------------------------------------------------------------
+
+[nt:nodeType]
+ - jcr:nodeTypeName (name) mandatory
+ - jcr:supertypes (name) multiple
+ - jcr:isMixin (boolean) mandatory
+ - jcr:hasOrderableChildNodes (boolean) mandatory
+ - jcr:primaryItemName (name)
+ + jcr:propertyDefinition (nt:propertyDefinition) = nt:propertyDefinition version
+ + jcr:childNodeDefinition (nt:childNodeDefinition) = nt:childNodeDefinition version
+
+[nt:propertyDefinition]
+ - jcr:name (name)
+ - jcr:autoCreated (boolean) mandatory
+ - jcr:mandatory (boolean) mandatory
+ - jcr:onParentVersion (string) mandatory
+ < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE',
'IGNORE', 'ABORT'
+ - jcr:protected (boolean) mandatory
+ - jcr:requiredType (string) mandatory
+ < 'STRING', 'BINARY', 'LONG', 'DOUBLE',
'BOOLEAN', 'DATE', 'NAME', 'PATH', 'REFERENCE',
'UNDEFINED'
+ - jcr:valueConstraints (string) multiple
+ - jcr:defaultValues (undefined) multiple
+ - jcr:multiple (boolean) mandatory
+
+[nt:childNodeDefinition]
+ - jcr:name (name)
+ - jcr:autoCreated (boolean) mandatory
+ - jcr:mandatory (boolean) mandatory
+ - jcr:onParentVersion (string) mandatory
+ < 'COPY', 'VERSION', 'INITIALIZE', 'COMPUTE',
'IGNORE', 'ABORT'
+ - jcr:protected (boolean) mandatory
+ - jcr:requiredPrimaryTypes (name) = 'nt:base' mandatory multiple
+ - jcr:defaultPrimaryType (name)
+ - jcr:sameNameSiblings (boolean) mandatory
+
+//------------------------------------------------------------------------------
+// M I S C
+//------------------------------------------------------------------------------
+
+[nt:hierarchyNode]
+ - jcr:created (date) autocreated protected initialize
+
+[nt:folder] > nt:hierarchyNode
+ + ex:generic (nt:hierarchyNode) version
+
+[nt:file] > nt:hierarchyNode
+ + jcr:content (nt:base) mandatory
+
+[nt:linkedFile] > nt:hierarchyNode
+ - jcr:content (reference) mandatory
+
+[nt:resource] > mix:referenceable
+ - jcr:encoding (string)
+ - jcr:mimeType (string) mandatory
+ - jcr:data (binary) mandatory
+ - jcr:lastModified (date) mandatory ignore
+
+[nt:query]
+ - jcr:statement (string)
+ - jcr:language (string)
+
+//------------------------------------------------------------------------------
+// J A C K R A B B I T I N T E R N A L S
+//------------------------------------------------------------------------------
+
+[REP:nodeTypes]
+ + ex:generic (nt:nodeType) = nt:nodeType protected abort
+
+[REP:root] > nt:unstructured
+ orderable
+ + jcr:system (REP:system) = REP:system mandatory ignore
+
+[REP:system]
+ orderable
+ + jcr:versionStorage (REP:versionStorage) = REP:versionStorage mandatory protected
abort
+ + jcr:nodeTypes (REP:nodeTypes) = REP:nodeTypes mandatory protected abort
+ + ex:generic (nt:base) = nt:unstructured ignore
+
+[REP:versionStorage]
+ + ex:generic1 (nt:versionHistory) = nt:versionHistory protected abort
+ + ex:generic2 (REP:versionStorage) = REP:versionStorage protected abort
\ No newline at end of file