r1339 - in xwiki/trunk/src: main/java/com/xpn/xwiki/plugin/query test/java/com/xpn/xwiki/test test/java/com/xpn/xwiki/test/plugin/query

Artem Melentev amelentev at users.forge.objectweb.org
Thu Sep 21 23:44:15 CEST 2006


Author: amelentev
Date: 2006-09-21 23:44:14 +0200 (Thu, 21 Sep 2006)
New Revision: 1339

Modified:
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/HibernateQuery.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/XWikiNamespaceResolver.java
   xwiki/trunk/src/test/java/com/xpn/xwiki/test/Utils.java
   xwiki/trunk/src/test/java/com/xpn/xwiki/test/plugin/query/QueryPluginTest.java
Log:
Add jcr:deref function support in QueryPlugin for Hibernate. Tests.
example:
/main/webhome/obj/xwiki/object/jcr:deref(@doc, '*')/@fullName
/main/webhome/attach/jcr:deref(@doc, '*')
//element(*, 'xwiki:object')/jcr:deref(@doc, '*')


Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/HibernateQuery.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/HibernateQuery.java	2006-09-21 14:36:55 UTC (rev 1338)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/HibernateQuery.java	2006-09-21 21:44:14 UTC (rev 1339)
@@ -98,7 +98,7 @@
 		_select.appendWithSep(p.getHqlName());
 	}
 	protected void _addPropClass(Class class1) {} // used in SecHibernateQuery
-		
+	
 	static QName fromJCRName(String s) {
 		try {
 			return QName.fromJCRName(s, XWikiNamespaceResolver.getInstance());
@@ -141,9 +141,9 @@
 	        // order by
 	        OrderQueryNode order = node.getOrderNode();
 	        QName mainclass = getLastQNClass();
-	        String mainobj = getLastNameClass(mainclass);
-	        Object[] args = new Object[]{mainobj, mainclass};
+	        String mainobj = getLastNameClass(mainclass);	        
 	        if (order != null) {
+	        	Object[] args = new Object[]{mainobj, mainclass};
 	            traverse(order, args);
 	        }
 	        QName[] select = node.getSelectProperties();
@@ -183,7 +183,7 @@
 					}
 					public Object visit(NodeTypeQueryNode node, Object data) {
 						nodesclass[ind] = node.getValue();
-						return super.visit(node, data);
+						return data;
 					}
 				}, null);
 			}
@@ -191,17 +191,24 @@
 				final LocationStepQueryNode lsqn = (LocationStepQueryNode) ps[i];
 				QName qn = lsqn.getNameTest();
 				QName xwcl = (QName) abr_xwiki_classes.get(qn);
+				if (ps.length-i>=2 && DerefQueryNode.class == ps[i+1].getClass()) {
+					if (qn_xwiki_attachment.equals(nodesclass[i]) || qn_xwiki_object.equals(nodesclass[i])) {
+						nodeflag[i+1] = true;
+						nodesclass[i+1] = qn_xwiki_document;
+					} else
+						throw new TranslateException("jcr:deref can be only after xwiki:object and xwiki:attachment");
+				}
 				if (ps.length-i>=2 && qn_xwiki_attachment.equals(xwcl) && !((LocationStepQueryNode)ps[i+1]).getIncludeDescendants()
-						&& nodesclass[i]==null && nodesclass[i+1]==null) {				
+						&& nodesclass[i]==null && nodesclass[i+1]==null) {
 					final NodeTypeQueryNode ntqn = new NodeTypeQueryNode(ps[i+1], xwcl);
 					nodesclass[i+1] = ntqn.getValue();
 					((LocationStepQueryNode)ps[i+1]).addOperand( ntqn );
 					nodeflag[i]=true;
 					nodeflag[i+1]=true;
 				}
-				if (ps.length-i>=3 && xwcl!=null && !((LocationStepQueryNode)ps[i+1]).getIncludeDescendants() 
+				if (ps.length-i>=3 && xwcl!=null && !((LocationStepQueryNode)ps[i+1]).getIncludeDescendants()
 						&& !((LocationStepQueryNode)ps[i+2]).getIncludeDescendants()
-						&& nodesclass[i]==null && nodesclass[i+1]==null && nodesclass[i+2]==null) {					
+						&& nodesclass[i]==null && nodesclass[i+1]==null && nodesclass[i+2]==null) {
 					final NodeTypeQueryNode ntqn = new NodeTypeQueryNode(ps[i+2], xwcl);
 					nodesclass[i+2] = ntqn.getValue();
 					((LocationStepQueryNode)ps[i+2]).addOperand( ntqn );
@@ -216,7 +223,7 @@
 					((LocationStepQueryNode)ps[i+1]).addOperand( ntqn );
 					nodeflag[i]=true;
 					nodeflag[i+1]=true;
-				}
+				}				
 			}
 			
 			// name[&space] in objects,docs,attachs
@@ -282,7 +289,7 @@
 				lastobj = (String) res[0];
 				lastclass = qncl;
 			}
-
+			
 			return data;
 		}
 		/** @param data - Object[]{String curname="", QName curclass, String ParentName, QName ParentClass } */
@@ -305,7 +312,7 @@
 				if (qn_xwiki_attachment.equals(qclass)) {
 					_where.appendWithSep(objname).append(".docId=").append(parentname).append(".id");
 				} else if (qn_xwiki_object.equals(qclass)) {
-					_where.appendWithSep(objname).append(".name=").append(parentname).append(".fullName");					
+					_where.appendWithSep(objname).append(".name=").append(parentname).append(".fullName");
 				} else if (qn_xwiki_document.equals(qclass)) {
 					_where.appendWithSep(objname).append(".parent=").append(parentname).append(".fullName");
 				}
@@ -458,7 +465,7 @@
 	        } else if (vt == QueryConstants.TYPE_LONG) {
 	        	_userwhere.append(node.getLongValue());
 	        } else if (vt == QueryConstants.TYPE_POSITION) {
-	        	_userwhere.append(node.getPositionValue()); // XXX: I don`t know that is it
+	        	_userwhere.append(node.getPositionValue()); // XXX: I don`t know that is it. [1]?
 	        } else if (vt == QueryConstants.TYPE_STRING) {
 	        	_userwhere.append("'").append(tosqlstring(node.getStringValue())).append("'");
 	        } else if (vt == QueryConstants.TYPE_TIMESTAMP || vt == QueryConstants.TYPE_DATE) {        		        	
@@ -500,20 +507,43 @@
 		}
 
 		public Object visit(DerefQueryNode node, Object data) {
-			throw new TranslateException("Not implemented");
+			final Object[] args = (Object[]) data;
+			QName parentclass = (QName) args[3];
+			String parentname = (String) args[2];
+			
+			if (qn_xwiki_object.equals(parentclass) || qn_xwiki_attachment.equals(parentclass)) {
+				if ("doc".equals( node.getRefProperty().getLocalName() )
+						&& "".equals(node.getRefProperty().getNamespaceURI())) {
+					String docobj = getLastNameClass(qn_xwiki_document);
+					_lastClass = qn_xwiki_document;
+					if (docobj==null) {
+						docobj = newXWikiObj(qn_xwiki_document);
+						if (qn_xwiki_attachment.equals(parentclass)) {
+							_where.appendWithSep(parentname).append(".docId=").append(docobj).append(".id");
+						} else { // qn_xwiki_object == parentclass)
+							_where.appendWithSep(parentname).append(".name=").append(docobj).append(".fullName");
+						}
+					}
+					args[0] = docobj;
+					// TODO: is operators, etc is possible in jcr:deref node?
+					return data;
+				} else
+					throw new TranslateException("jcr:deref is possible only by jcr:deref(@doc,'*')");
+			} else
+				throw new TranslateException("jcr:deref is possible only from xwiki:object and xwiki:attachment");
 		}
 		
 		private int indent;
-		private final void traverse(QueryNode[] node, Object buffer) {
+		private final void traverse(QueryNode[] node, Object data) {
 	        indent ++;
 	        for (int i = 0; i < node.length; i++) {
-	            node[i].accept(this, buffer);
+	            node[i].accept(this, data);
 	        }
 	        indent --;
 	    }
-		private final Object traverse(QueryNode node, Object buffer) {			
+		private final Object traverse(QueryNode node, Object data) {			
 			indent ++;
-			final Object r = node.accept(this, buffer);
+			final Object r = node.accept(this, data);
 			indent --;
 			return r;
 		}
@@ -530,7 +560,7 @@
 			}
 			return null;			
 		}
-				
+		
 		private final String n2e(String s) {
 			return s==null?"":s;
 		}
@@ -569,7 +599,7 @@
 				return new ObjPropProperty(obj, objjclass, prop);
 			
 			if (!qn_xwiki_object.equals(objclass))
-				throw new TranslateException("flex attributes is only for xwiki:object");
+				throw new TranslateException("xp: attributes is only for xwiki:object");
 			
 			final String classname = (String) _objClassName.get(obj);
 			if (classname==null)

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/XWikiNamespaceResolver.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/XWikiNamespaceResolver.java	2006-09-21 14:36:55 UTC (rev 1338)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/query/XWikiNamespaceResolver.java	2006-09-21 21:44:14 UTC (rev 1339)
@@ -43,6 +43,8 @@
     	NS_OBJ_URI = "BaseObject",
     	NS_XWIKI_PREFFIX	= "xwiki",
     	NS_XWIKI_URI		= "http://www.xwiki.org/";
+    	//NS_XWIKI_PROPERTY_PREFFIX	= "xp",
+    	//NS_XWIKI_PROPERTY_URI		= "http://www.xwiki.org/property";
     private static void addnamespace(String pref, String uri) {
     	prefixToURI.put(pref, uri);
     	uriToPrefix.put(uri, pref);
@@ -71,9 +73,10 @@
         
         // XWiki namespaces
         addnamespace(NS_FLEX_PREFFIX, NS_FLEX_URI);
-        addnamespace(NS_DOC_PREFFIX, NS_DOC_URI);
-        addnamespace(NS_OBJ_PREFFIX, NS_OBJ_URI);
-        addnamespace(NS_XWIKI_PREFFIX, NS_XWIKI_URI);        
+        addnamespace(NS_DOC_PREFFIX, NS_DOC_URI);   // XXX: hibernate-specific
+        addnamespace(NS_OBJ_PREFFIX, NS_OBJ_URI);   // XXX: hibernate-specific
+        addnamespace(NS_XWIKI_PREFFIX, NS_XWIKI_URI);
+        //addnamespace(NS_XWIKI_PROPERTY_PREFFIX, NS_XWIKI_PROPERTY_URI);
     }
 	
 	public String getURI(String prefix) throws NamespaceException {

Modified: xwiki/trunk/src/test/java/com/xpn/xwiki/test/Utils.java
===================================================================
--- xwiki/trunk/src/test/java/com/xpn/xwiki/test/Utils.java	2006-09-21 14:36:55 UTC (rev 1338)
+++ xwiki/trunk/src/test/java/com/xpn/xwiki/test/Utils.java	2006-09-21 21:44:14 UTC (rev 1339)
@@ -49,6 +49,7 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.BaseCollection;
 import com.xpn.xwiki.objects.BaseElement;
@@ -236,6 +237,16 @@
                                      Map bobjects, XWikiContext context) throws XWikiException {
               return createDoc(store, web, name, content1, bobject, bclass, bobjects, context);
         }
+    
+    public static XWikiAttachment createAttachment(XWikiStoreInterface store, XWikiDocument doc, String attname, String filename, XWikiContext context) throws IOException, XWikiException {
+    	XWikiAttachment attachment = new XWikiAttachment(doc, attname);
+        byte[] attachcontent = Utils.getDataAsBytes(new File(filename));
+        attachment.setContent(attachcontent);
+        doc.getAttachmentList().add(attachment);
+        doc.saveAttachmentContent(attachment, context);
+        store.saveXWikiDoc(doc, context);
+        return attachment;
+    }
 
     public static BaseObject prepareObject(XWikiDocument doc) throws XWikiException {
         return prepareObject(doc, "Test.TestObject");

Modified: xwiki/trunk/src/test/java/com/xpn/xwiki/test/plugin/query/QueryPluginTest.java
===================================================================
--- xwiki/trunk/src/test/java/com/xpn/xwiki/test/plugin/query/QueryPluginTest.java	2006-09-21 14:36:55 UTC (rev 1338)
+++ xwiki/trunk/src/test/java/com/xpn/xwiki/test/plugin/query/QueryPluginTest.java	2006-09-21 21:44:14 UTC (rev 1339)
@@ -26,8 +26,8 @@
 import java.io.IOException;
 import java.sql.Timestamp;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.List;
-import java.util.Date;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.ValueFormatException;
@@ -45,12 +45,10 @@
 import com.xpn.xwiki.plugin.XWikiPluginManager;
 import com.xpn.xwiki.plugin.query.IQueryFactory;
 import com.xpn.xwiki.plugin.query.QueryPlugin;
-import com.xpn.xwiki.plugin.query.XWikiQuery;
 import com.xpn.xwiki.store.XWikiHibernateStore;
 import com.xpn.xwiki.store.XWikiStoreInterface;
 import com.xpn.xwiki.test.HibernateTestCase;
 import com.xpn.xwiki.test.Utils;
-import junit.framework.TestCase;
 
 public class QueryPluginTest extends HibernateTestCase {
     private static final Object[] NOTHING = new Object[]{};
@@ -94,7 +92,7 @@
             } else {
                 obj = loadobj(obj);
                 exp = loadobj(exp);
-                if (exp==obj) continue; // XXX: bugs with proxy objects?
+                if (exp==obj) continue;
                 if (exp instanceof XWikiDocument)
                  assertEquals("Objects #"+i+" not equals",
                          ((XWikiDocument)obj).toFullXML(context),
@@ -322,7 +320,7 @@
         doc2.setContent("no content");
         doc2.setAuthor("Someone over");
         doc2.setParent("Test.WebHome");
-        hb.saveXWikiDoc(doc2, getXWikiContext()); // XXX: Was same attachments of different documents be? That would query return? 2 or 1
+        hb.saveXWikiDoc(doc2, getXWikiContext());
 
         XWikiAttachment attachment3 = new XWikiAttachment(doc2, "testfile1");
         byte[] attachcontent3 = Utils.getDataAsBytes(new File(Utils.filename));
@@ -616,7 +614,7 @@
     }
 
     public void testDates() throws XWikiException, ValueFormatException, IllegalStateException, RepositoryException {
-//		 new Class
+    	// new Class
         XWikiDocument doc0, doc = doc0 = new XWikiDocument("Class", "Class1");
         BaseClass bclass = new BaseClass();
         bclass.addDateField("date", "pdate");
@@ -651,4 +649,32 @@
         testSearchXPnQl1("//obj/Class/Class1[@f:date > xs:dateTime('"+sdate+"')]/@f:date", "select f:date from xwiki:object where className='Class.Class1' and f:date > TIMESTAMP '"+sdate+"'", ts2);
         testSearchXPnQl("//obj/Class/Class1[@f:date >= xs:dateTime('"+sdate+"')]/@f:date  order by @f:date descending", "select f:date from xwiki:object where className='Class.Class1' and f:date >= TIMESTAMP '"+sdate+"' order by f:date DESC", new Object[]{ts2, ts1});
     }
+    public void testJcrDeref() throws XWikiException, IOException, InvalidQueryException {
+    	XWikiStoreInterface store = xwiki.getStore();
+    	Utils.setStandardData();
+    	XWikiDocument doc1 = Utils.createDoc("Test.JcrDeref", "content", store, context);
+    	XWikiAttachment att1 = Utils.createAttachment(store, doc1, "testatt1", Utils.filename, context);
+        
+    	testSearchXP1("/*/*", doc1);
+    	testSearchXP1("/*/*/attach/testatt1", att1);
+        testSearchXP1("/*/*/attach/testatt1/jcr:deref(@doc, '*')", doc1);
+        testSearchXP1("/*/*/attach/*/jcr:deref(@doc, '*')/@fullName", doc1.getFullName());
+        
+        XWikiDocument doc2 = Utils.createDoc("Test.JcrDeref2", "content2", store, context);
+        Utils.createAttachment(store, doc2, "testatt1", Utils.filename, context);
+        
+        testSearchXP("/*/*/attach/testatt1/jcr:deref(@doc, '*') order by @fullName", new Object[]{doc1, doc2});
+        testSearchXP1("/*/*[@content='content2']/attach/*/jcr:deref(@doc, '*')/@fullName", doc2.getFullName());
+        
+        BaseObject bo = Utils.prepareObject(doc1, doc1.getFullName());
+        xwiki.saveDocument(doc1, context);
+        testSearchXP1("/*/*/obj/*/*", bo);
+        testSearchXP1("/*/*/obj/*/*/jcr:deref(@doc, '*')", doc1);
+        testSearchXP1("/*/*/obj/*/*/jcr:deref(@doc, '*')/obj/Test/JcrDeref", bo);
+        testSearchXP1("/*/*/obj/*/*/jcr:deref(@doc, '*')/obj/Test/JcrDeref/jcr:deref(@doc, '*')", doc1);
+        testSearchXP1("/*/*/obj/Test/JcrDeref/jcr:deref(@doc, '*')/attach/testatt1", att1);
+        testSearchXP1("/*/*/obj/*/*/jcr:deref(@doc, '*')/attach/*/jcr:deref(@doc, '*')", doc1);
+        testSearchXP("//element(*, xwiki:attachment)/jcr:deref(@doc, '*')/@content order by @name", new Object[]{doc1.getContent(),doc2.getContent()});
+        testSearchXP1("//element(*, xwiki:object)/jcr:deref(@doc, '*')", doc1);
+    }
 }





More information about the Xwiki-notifications mailing list