You can subscribe to this list here.
| 2004 |
Jan
|
Feb
|
Mar
(57) |
Apr
(103) |
May
(164) |
Jun
(139) |
Jul
(173) |
Aug
(196) |
Sep
(221) |
Oct
(333) |
Nov
(214) |
Dec
(88) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2005 |
Jan
(163) |
Feb
(165) |
Mar
(98) |
Apr
(93) |
May
(199) |
Jun
(118) |
Jul
(200) |
Aug
(212) |
Sep
(185) |
Oct
(297) |
Nov
(437) |
Dec
(272) |
| 2006 |
Jan
(542) |
Feb
(329) |
Mar
(267) |
Apr
(332) |
May
(267) |
Jun
(130) |
Jul
(161) |
Aug
(348) |
Sep
(166) |
Oct
(305) |
Nov
(173) |
Dec
(173) |
| 2007 |
Jan
(199) |
Feb
(118) |
Mar
(133) |
Apr
(200) |
May
(208) |
Jun
(146) |
Jul
(198) |
Aug
(146) |
Sep
(187) |
Oct
(182) |
Nov
(181) |
Dec
(83) |
| 2008 |
Jan
(252) |
Feb
(124) |
Mar
(124) |
Apr
(101) |
May
(143) |
Jun
(122) |
Jul
(129) |
Aug
(60) |
Sep
(80) |
Oct
(89) |
Nov
(54) |
Dec
(112) |
| 2009 |
Jan
(88) |
Feb
(145) |
Mar
(105) |
Apr
(164) |
May
(123) |
Jun
(154) |
Jul
(374) |
Aug
(341) |
Sep
(219) |
Oct
(137) |
Nov
(373) |
Dec
(240) |
| 2010 |
Jan
(197) |
Feb
(270) |
Mar
(253) |
Apr
(150) |
May
(102) |
Jun
(51) |
Jul
(300) |
Aug
(512) |
Sep
(254) |
Oct
(258) |
Nov
(288) |
Dec
(143) |
| 2011 |
Jan
(238) |
Feb
(179) |
Mar
(253) |
Apr
(332) |
May
(248) |
Jun
(255) |
Jul
(216) |
Aug
(282) |
Sep
(146) |
Oct
(77) |
Nov
(86) |
Dec
(69) |
| 2012 |
Jan
(172) |
Feb
(234) |
Mar
(229) |
Apr
(101) |
May
(212) |
Jun
(267) |
Jul
(129) |
Aug
(210) |
Sep
(239) |
Oct
(271) |
Nov
(368) |
Dec
(220) |
| 2013 |
Jan
(179) |
Feb
(155) |
Mar
(59) |
Apr
(47) |
May
(99) |
Jun
(158) |
Jul
(185) |
Aug
(16) |
Sep
(16) |
Oct
(7) |
Nov
(20) |
Dec
(12) |
| 2014 |
Jan
(21) |
Feb
(17) |
Mar
(18) |
Apr
(13) |
May
(27) |
Jun
(15) |
Jul
(19) |
Aug
(22) |
Sep
(30) |
Oct
(16) |
Nov
(19) |
Dec
(16) |
| 2015 |
Jan
(14) |
Feb
(24) |
Mar
(33) |
Apr
(41) |
May
(14) |
Jun
(80) |
Jul
(53) |
Aug
(8) |
Sep
(7) |
Oct
(15) |
Nov
(13) |
Dec
(2) |
| 2016 |
Jan
(22) |
Feb
(12) |
Mar
(30) |
Apr
(6) |
May
(33) |
Jun
(16) |
Jul
(8) |
Aug
(20) |
Sep
(12) |
Oct
(18) |
Nov
(12) |
Dec
(11) |
| 2017 |
Jan
(24) |
Feb
(26) |
Mar
(47) |
Apr
(23) |
May
(19) |
Jun
(14) |
Jul
(28) |
Aug
(30) |
Sep
(17) |
Oct
|
Nov
|
Dec
|
| 2019 |
Jan
(1) |
Feb
(73) |
Mar
(90) |
Apr
(42) |
May
(116) |
Jun
(90) |
Jul
(127) |
Aug
(103) |
Sep
(56) |
Oct
(42) |
Nov
(95) |
Dec
(58) |
| 2020 |
Jan
(102) |
Feb
(31) |
Mar
(93) |
Apr
(60) |
May
(57) |
Jun
(45) |
Jul
(29) |
Aug
(32) |
Sep
(44) |
Oct
(86) |
Nov
(51) |
Dec
(71) |
| 2021 |
Jan
(44) |
Feb
(25) |
Mar
(78) |
Apr
(130) |
May
(64) |
Jun
(74) |
Jul
(21) |
Aug
(64) |
Sep
(40) |
Oct
(43) |
Nov
(21) |
Dec
(99) |
| 2022 |
Jan
(154) |
Feb
(64) |
Mar
(45) |
Apr
(95) |
May
(62) |
Jun
(48) |
Jul
(73) |
Aug
(37) |
Sep
(71) |
Oct
(27) |
Nov
(40) |
Dec
(65) |
| 2023 |
Jan
(89) |
Feb
(130) |
Mar
(124) |
Apr
(50) |
May
(93) |
Jun
(46) |
Jul
(45) |
Aug
(68) |
Sep
(62) |
Oct
(71) |
Nov
(108) |
Dec
(82) |
| 2024 |
Jan
(53) |
Feb
(76) |
Mar
(64) |
Apr
(75) |
May
(36) |
Jun
(54) |
Jul
(98) |
Aug
(137) |
Sep
(58) |
Oct
(177) |
Nov
(84) |
Dec
(52) |
| 2025 |
Jan
(70) |
Feb
(53) |
Mar
(72) |
Apr
(47) |
May
(88) |
Jun
(49) |
Jul
(86) |
Aug
(51) |
Sep
(65) |
Oct
(91) |
Nov
(18) |
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
1
(8) |
2
(10) |
3
(4) |
4
(2) |
5
(2) |
|
6
(2) |
7
(1) |
8
(11) |
9
(7) |
10
(5) |
11
(4) |
12
(2) |
|
13
(6) |
14
(6) |
15
(12) |
16
(9) |
17
(12) |
18
(1) |
19
(5) |
|
20
(14) |
21
(1) |
22
(13) |
23
(7) |
24
(8) |
25
(5) |
26
|
|
27
(4) |
28
(2) |
29
(34) |
30
(6) |
31
(9) |
|
|
|
From: <di...@us...> - 2012-05-31 20:37:35
|
Revision: 16517
http://exist.svn.sourceforge.net/exist/?rev=16517&view=rev
Author: dizzzz
Date: 2012-05-31 20:37:29 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] bugfix, mixedup variables
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:28:13 UTC (rev 16516)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:37:29 UTC (rev 16517)
@@ -639,10 +639,10 @@
broker = brokerPool.get(brokerPool.getSecurityManager().getSystemSubject());
// Open collection if possible, else abort
- srcCollection = broker.openCollection(sourceColURI, Lock.WRITE_LOCK);
+ srcCollection = broker.openCollection(sourcePath, Lock.WRITE_LOCK);
if (srcCollection == null) {
txnManager.abort(txn);
- throw new JMSReceiveException("Collection " + sourceColURI + " does not exist.");
+ throw new JMSReceiveException("Collection " + sourcePath + " does not exist.");
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-31 20:28:19
|
Revision: 16516
http://exist.svn.sourceforge.net/exist/?rev=16516&view=rev
Author: dizzzz
Date: 2012-05-31 20:28:13 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] bugfix, mixedup variables
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:09:04 UTC (rev 16515)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:28:13 UTC (rev 16516)
@@ -537,8 +537,8 @@
XmldbURI sourceDocURI = sourcePath.lastSegment();
XmldbURI destPath = XmldbURI.create(em.getDestinationPath());
- XmldbURI destColURI = sourcePath.removeLastSegment();
- XmldbURI destDocURI = sourcePath.lastSegment();
+ XmldbURI destColURI = destPath.removeLastSegment();
+ XmldbURI destDocURI = destPath.lastSegment();
DBBroker broker = null;
@@ -559,7 +559,7 @@
srcCollection = broker.openCollection(sourceColURI, Lock.WRITE_LOCK);
if (srcCollection == null) {
txnManager.abort(txn);
- throw new JMSReceiveException("Collection not found: " + sourcePath);
+ throw new JMSReceiveException("Collection not found: " + sourceColURI);
}
// Open document if possible, else abort
@@ -573,9 +573,9 @@
// Open collection if possible, else abort
destCollection = broker.openCollection(destColURI, Lock.WRITE_LOCK);
if (destCollection == null) {
- LOG.debug("Destination collection " + destPath + " does not exist.");
+ LOG.debug("Destination collection " + destColURI + " does not exist.");
txnManager.abort(txn);
- throw new JMSReceiveException("Destination collection " + destPath + " does not exist.");
+ throw new JMSReceiveException("Destination collection " + destColURI + " does not exist.");
}
@@ -623,8 +623,8 @@
XmldbURI sourceDocURI = sourcePath.lastSegment();
XmldbURI destPath = XmldbURI.create(em.getDestinationPath());
- XmldbURI destColURI = sourcePath.removeLastSegment();
- XmldbURI destDocURI = sourcePath.lastSegment();
+ XmldbURI destColURI = destPath.removeLastSegment();
+ XmldbURI destDocURI = destPath.lastSegment();
DBBroker broker = null;
Collection srcCollection = null;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-31 20:09:10
|
Revision: 16515
http://exist.svn.sourceforge.net/exist/?rev=16515&view=rev
Author: dizzzz
Date: 2012-05-31 20:09:04 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] Added copy/move functions (need to be tested still), some refactoring.
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:04:14 UTC (rev 16514)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:09:04 UTC (rev 16515)
@@ -23,7 +23,6 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.jms.BytesMessage;
@@ -31,21 +30,20 @@
import javax.jms.Message;
import javax.jms.MessageListener;
import org.apache.log4j.Logger;
-import org.exist.EXistException;
import org.exist.clustering.triggers.eXistMessage;
import org.exist.clustering.triggers.eXistMessageImpl;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
-import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
-import org.exist.security.PermissionDeniedException;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
-import org.exist.util.*;
-import org.exist.webdav.ExistResource;
+import org.exist.util.MimeTable;
+import org.exist.util.MimeType;
+import org.exist.util.VirtualTempFile;
+import org.exist.util.VirtualTempFileInputSource;
import org.exist.xmldb.XmldbURI;
import org.xml.sax.InputSource;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-31 20:04:21
|
Revision: 16514
http://exist.svn.sourceforge.net/exist/?rev=16514&view=rev
Author: dizzzz
Date: 2012-05-31 20:04:14 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] Added copy/move functions (need to be tested still), some refactoring.
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Added Paths:
-----------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/JMSReceiveException.java
Removed Paths:
-------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java
Deleted: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java 2012-05-31 18:31:53 UTC (rev 16513)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java 2012-05-31 20:04:14 UTC (rev 16514)
@@ -1,47 +0,0 @@
-/*
- * eXist Open Source Native XML Database
- * Copyright (C) 2012 The eXist Project
- * http://exist-db.org
- *
- * This program 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
- * of the License, or (at your option) any later version.
- *
- * This program 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 library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * $Id$
- */
-package org.exist.clustering.triggers.receive;
-
-/**
- * Class for reporting problems during handling received messages. Must
- * be a runtime exception.
- *
- * @author Dannes Wessels
- */
-public class HandeMessageException extends RuntimeException {
-
- public HandeMessageException() {
- super();
- }
-
- public HandeMessageException(String msg) {
- super(msg);
- }
-
- public HandeMessageException(Throwable t) {
- super(t);
- }
-
- public HandeMessageException(String msg, Throwable t) {
- super(msg, t);
- }
-}
Copied: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/JMSReceiveException.java (from rev 16513, branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java)
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/JMSReceiveException.java (rev 0)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/JMSReceiveException.java 2012-05-31 20:04:14 UTC (rev 16514)
@@ -0,0 +1,47 @@
+/*
+ * eXist Open Source Native XML Database
+ * Copyright (C) 2012 The eXist Project
+ * http://exist-db.org
+ *
+ * This program 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * $Id$
+ */
+package org.exist.clustering.triggers.receive;
+
+/**
+ * Class for reporting problems during handling received messages. Must
+ * be a runtime exception.
+ *
+ * @author Dannes Wessels
+ */
+public class JMSReceiveException extends RuntimeException {
+
+ public JMSReceiveException() {
+ super();
+ }
+
+ public JMSReceiveException(String msg) {
+ super(msg);
+ }
+
+ public JMSReceiveException(Throwable t) {
+ super(t);
+ }
+
+ public JMSReceiveException(String msg, Throwable t) {
+ super(msg, t);
+ }
+}
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 18:31:53 UTC (rev 16513)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 20:04:14 UTC (rev 16514)
@@ -23,6 +23,7 @@
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.jms.BytesMessage;
@@ -30,20 +31,21 @@
import javax.jms.Message;
import javax.jms.MessageListener;
import org.apache.log4j.Logger;
+import org.exist.EXistException;
import org.exist.clustering.triggers.eXistMessage;
import org.exist.clustering.triggers.eXistMessageImpl;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
+import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
+import org.exist.security.PermissionDeniedException;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
-import org.exist.util.MimeTable;
-import org.exist.util.MimeType;
-import org.exist.util.VirtualTempFile;
-import org.exist.util.VirtualTempFileInputSource;
+import org.exist.util.*;
+import org.exist.webdav.ExistResource;
import org.exist.xmldb.XmldbURI;
import org.xml.sax.InputSource;
@@ -100,7 +102,7 @@
String errorMessage = "Unable to convert incoming message. ("
+ ex.getErrorCode() + "): " + ex.getMessage();
LOG.error(errorMessage, ex);
- throw new HandeMessageException(errorMessage);
+ throw new JMSReceiveException(errorMessage);
}
return em;
@@ -143,24 +145,24 @@
default:
String errorMessage = "Unknown resource type " + em.getResourceType();
LOG.error(errorMessage);
- throw new HandeMessageException(errorMessage);
+ throw new JMSReceiveException(errorMessage);
}
} else {
// Only ByteMessage objects supported.
- throw new HandeMessageException("Could not handle message type "
+ throw new JMSReceiveException("Could not handle message type "
+ msg.getClass().getSimpleName());
}
- } catch (HandeMessageException ex) {
+ } catch (JMSReceiveException ex) {
// Thrown by local code. Just make it pass
LOG.error("Could not handle received message: " + ex.getMessage());
throw ex;
} catch (Throwable t) {
// Something really unexpected happened. Report
- throw new HandeMessageException("Could not handle received message: "
+ throw new JMSReceiveException("Could not handle received message: "
+ t.getMessage(), t);
}
}
@@ -182,17 +184,17 @@
break;
case MOVE:
- //
+ relocateDocument(em, false);
break;
case COPY:
- //
+ relocateDocument(em, true);
break;
default:
String errorMessage = "Unknown resource type " + em.getChangeType();
LOG.error(errorMessage);
- throw new HandeMessageException(errorMessage);
+ throw new JMSReceiveException(errorMessage);
}
}
@@ -214,11 +216,11 @@
break;
case MOVE:
- //
+ relocateCollection(em, false);
break;
case COPY:
- //
+ relocateCollection(em,true);
break;
default:
@@ -322,7 +324,7 @@
} catch (Throwable ex) {
LOG.error(ex.getMessage(), ex);
transact.abort(txn);
- throw new HandeMessageException("Unable to write document into database: " + ex.getMessage());
+ throw new JMSReceiveException("Unable to write document into database: " + ex.getMessage());
} finally {
@@ -393,7 +395,7 @@
} catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
- throw new HandeMessageException(e.getMessage(), e);
+ throw new JMSReceiveException(e.getMessage(), e);
} finally {
@@ -452,7 +454,7 @@
} catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
- throw new HandeMessageException(e.getMessage());
+ throw new JMSReceiveException(e.getMessage());
} finally {
@@ -492,10 +494,10 @@
// TODO ... consider to swallow situation transparently
collection = broker.openCollection(sourcePath, Lock.WRITE_LOCK);
if (collection != null) {
- String errorText="Collection " + sourcePath + " already exists";
+ String errorText = "Collection " + sourcePath + " already exists";
LOG.debug(errorText);
transact.abort(txn);
- throw new HandeMessageException(errorText);
+ throw new JMSReceiveException(errorText);
}
// Create collection
@@ -513,7 +515,7 @@
} catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
- throw new HandeMessageException(e.getMessage(), e);
+ throw new JMSReceiveException(e.getMessage(), e);
} finally {
@@ -529,4 +531,164 @@
}
}
}
+
+ private void relocateDocument(eXistMessage em, boolean keepDocument) {
+
+ XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
+ XmldbURI sourceColURI = sourcePath.removeLastSegment();
+ XmldbURI sourceDocURI = sourcePath.lastSegment();
+
+ XmldbURI destPath = XmldbURI.create(em.getDestinationPath());
+ XmldbURI destColURI = sourcePath.removeLastSegment();
+ XmldbURI destDocURI = sourcePath.lastSegment();
+
+
+ DBBroker broker = null;
+
+ Collection srcCollection = null;
+ DocumentImpl srcDocument = null;
+
+ Collection destCollection = null;
+
+ TransactionManager txnManager = brokerPool.getTransactionManager();
+ Txn txn = txnManager.beginTransaction();
+
+ try {
+ // TODO get user
+ broker = brokerPool.get(brokerPool.getSecurityManager().getSystemSubject());
+
+ // Open collection if possible, else abort
+ srcCollection = broker.openCollection(sourceColURI, Lock.WRITE_LOCK);
+ if (srcCollection == null) {
+ txnManager.abort(txn);
+ throw new JMSReceiveException("Collection not found: " + sourcePath);
+ }
+
+ // Open document if possible, else abort
+ srcDocument = srcCollection.getDocument(broker, sourceDocURI);
+ if (srcDocument == null) {
+ LOG.debug("No resource found for path: " + sourcePath);
+ txnManager.abort(txn);
+ throw new JMSReceiveException("No resource found for path: " + sourcePath);
+ }
+
+ // Open collection if possible, else abort
+ destCollection = broker.openCollection(destColURI, Lock.WRITE_LOCK);
+ if (destCollection == null) {
+ LOG.debug("Destination collection " + destPath + " does not exist.");
+ txnManager.abort(txn);
+ throw new JMSReceiveException("Destination collection " + destPath + " does not exist.");
+ }
+
+
+ // Perform actial move/copy
+ if (keepDocument) {
+ broker.copyResource(txn, srcDocument, destCollection, destDocURI);
+
+ } else {
+ broker.moveResource(txn, srcDocument, destCollection, destDocURI);
+ }
+
+
+ // Commit change
+ txnManager.commit(txn);
+
+
+
+ } catch (Throwable e) {
+ LOG.error(e);
+ txnManager.abort(txn);
+ throw new JMSReceiveException(e.getMessage(), e);
+
+ } finally {
+
+ // TODO: check if can be done earlier
+ if (destCollection != null) {
+ destCollection.release(Lock.WRITE_LOCK);
+ }
+
+ if (srcCollection != null) {
+ srcCollection.release(Lock.WRITE_LOCK);
+ }
+
+
+ brokerPool.release(broker);
+
+
+ }
+ }
+
+ private void relocateCollection(eXistMessage em, boolean keepCollection) {
+
+ XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
+ XmldbURI sourceColURI = sourcePath.removeLastSegment();
+ XmldbURI sourceDocURI = sourcePath.lastSegment();
+
+ XmldbURI destPath = XmldbURI.create(em.getDestinationPath());
+ XmldbURI destColURI = sourcePath.removeLastSegment();
+ XmldbURI destDocURI = sourcePath.lastSegment();
+
+ DBBroker broker = null;
+ Collection srcCollection = null;
+ Collection destCollection = null;
+
+
+ TransactionManager txnManager = brokerPool.getTransactionManager();
+ Txn txn = txnManager.beginTransaction();
+
+ try {
+ // TODO get user
+ broker = brokerPool.get(brokerPool.getSecurityManager().getSystemSubject());
+
+ // Open collection if possible, else abort
+ srcCollection = broker.openCollection(sourceColURI, Lock.WRITE_LOCK);
+ if (srcCollection == null) {
+ txnManager.abort(txn);
+ throw new JMSReceiveException("Collection " + sourceColURI + " does not exist.");
+ }
+
+
+ // Open collection if possible, else abort
+ destCollection = broker.openCollection(destColURI, Lock.WRITE_LOCK);
+ if (destCollection == null) {
+ LOG.debug("Destination collection " + destColURI + " does not exist.");
+ txnManager.abort(txn);
+ throw new JMSReceiveException("Destination collection " + destColURI + " does not exist.");
+ }
+
+ // Perform actual move/copy
+ if (keepCollection) {
+ broker.copyCollection(txn, srcCollection, destCollection, destDocURI);
+
+ } else {
+ broker.moveCollection(txn, srcCollection, destCollection, destDocURI);
+ }
+
+ // Commit change
+ txnManager.commit(txn);
+
+
+
+
+ } catch (Throwable e) {
+ LOG.error(e);
+ txnManager.abort(txn);
+ throw new JMSReceiveException(e.getMessage());
+
+ } finally {
+
+ if (destCollection != null) {
+ destCollection.release(Lock.WRITE_LOCK);
+ }
+
+ if (srcCollection != null) {
+ srcCollection.release(Lock.WRITE_LOCK);
+ }
+
+
+ brokerPool.release(broker);
+
+
+ }
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-31 18:32:00
|
Revision: 16513
http://exist.svn.sourceforge.net/exist/?rev=16513&view=rev
Author: dizzzz
Date: 2012-05-31 18:31:53 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] refactoring, improved error handling
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Added Paths:
-----------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java
Added: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java (rev 0)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/HandeMessageException.java 2012-05-31 18:31:53 UTC (rev 16513)
@@ -0,0 +1,47 @@
+/*
+ * eXist Open Source Native XML Database
+ * Copyright (C) 2012 The eXist Project
+ * http://exist-db.org
+ *
+ * This program 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
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * $Id$
+ */
+package org.exist.clustering.triggers.receive;
+
+/**
+ * Class for reporting problems during handling received messages. Must
+ * be a runtime exception.
+ *
+ * @author Dannes Wessels
+ */
+public class HandeMessageException extends RuntimeException {
+
+ public HandeMessageException() {
+ super();
+ }
+
+ public HandeMessageException(String msg) {
+ super(msg);
+ }
+
+ public HandeMessageException(Throwable t) {
+ super(t);
+ }
+
+ public HandeMessageException(String msg, Throwable t) {
+ super(msg, t);
+ }
+}
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 15:04:50 UTC (rev 16512)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-31 18:31:53 UTC (rev 16513)
@@ -21,27 +21,29 @@
*/
package org.exist.clustering.triggers.receive;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import org.apache.log4j.Logger;
-import org.exist.EXistException;
import org.exist.clustering.triggers.eXistMessage;
import org.exist.clustering.triggers.eXistMessageImpl;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
-import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
-import org.exist.security.PermissionDeniedException;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
-import org.exist.util.*;
+import org.exist.util.MimeTable;
+import org.exist.util.MimeType;
+import org.exist.util.VirtualTempFile;
+import org.exist.util.VirtualTempFileInputSource;
import org.exist.xmldb.XmldbURI;
import org.xml.sax.InputSource;
@@ -57,7 +59,7 @@
/**
* Constructor
*
- * @param brokerpool Database brokerpool
+ * @param brokerpool Reference to database brokerpool
*/
public eXistJMSListener(BrokerPool brokerpool) {
brokerPool = brokerpool;
@@ -95,7 +97,10 @@
em.setPayload(payload);
} catch (JMSException ex) {
- LOG.error(ex);
+ String errorMessage = "Unable to convert incoming message. ("
+ + ex.getErrorCode() + "): " + ex.getMessage();
+ LOG.error(errorMessage, ex);
+ throw new HandeMessageException(errorMessage);
}
return em;
@@ -105,36 +110,58 @@
@Override
public void onMessage(Message msg) {
- if (msg instanceof BytesMessage) {
- BytesMessage bm = (BytesMessage) msg;
+ try {
- eXistMessage em = convertMessage(bm);
+ if (msg instanceof BytesMessage) {
- String txt = em.getChangeType() + " : " + em.getResourceType()
- + " from " + em.getResourcePath();
- if (em.getDestinationPath() != null) {
- txt = txt + " to " + em.getDestinationPath();
- }
+ // Prepare received message
+ BytesMessage bm = (BytesMessage) msg;
+ eXistMessage em = convertMessage(bm);
- LOG.info(txt);
+ // Report some details into logging
+ if (LOG.isDebugEnabled()) {
+ String txt = em.getChangeType() + " : " + em.getResourceType()
+ + " from " + em.getResourcePath();
+ if (em.getDestinationPath() != null) {
+ txt = txt + " to " + em.getDestinationPath();
+ }
+ LOG.debug(txt);
+ }
- switch (em.getResourceType()) {
- case DOCUMENT:
- LOG.info("document");
- handleDocument(em);
- break;
- case COLLECTION:
- LOG.info("collection");
- handleCollection(em);
- break;
- default:
- LOG.error("Unknown resource type");
- break;
+ // First step: distinct between update for documents and messsages
+ switch (em.getResourceType()) {
+ case DOCUMENT:
+ LOG.info("document");
+ handleDocument(em);
+ break;
+ case COLLECTION:
+ LOG.info("collection");
+ handleCollection(em);
+ break;
+ default:
+ String errorMessage = "Unknown resource type " + em.getResourceType();
+ LOG.error(errorMessage);
+ throw new HandeMessageException(errorMessage);
+
+ }
+
+ } else {
+ // Only ByteMessage objects supported.
+ throw new HandeMessageException("Could not handle message type "
+ + msg.getClass().getSimpleName());
}
+ } catch (HandeMessageException ex) {
+ // Thrown by local code. Just make it pass
+ LOG.error("Could not handle received message: " + ex.getMessage());
+ throw ex;
+ } catch (Throwable t) {
+ // Something really unexpected happened. Report
+ throw new HandeMessageException("Could not handle received message: "
+ + t.getMessage(), t);
}
}
@@ -163,7 +190,9 @@
break;
default:
- LOG.error("Unknown change type");
+ String errorMessage = "Unknown resource type " + em.getChangeType();
+ LOG.error(errorMessage);
+ throw new HandeMessageException(errorMessage);
}
}
@@ -197,6 +226,9 @@
}
}
+ /**
+ * Created document in database
+ */
private void createDocument(eXistMessage em) {
@@ -287,9 +319,10 @@
LOG.debug("Document created sucessfully");
}
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.error(ex.getMessage(), ex);
transact.abort(txn);
+ throw new HandeMessageException("Unable to write document into database: " + ex.getMessage());
} finally {
@@ -306,6 +339,9 @@
}
}
+ /**
+ * Remove document from database
+ */
private void deleteDocument(eXistMessage em) {
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
@@ -354,22 +390,11 @@
LOG.debug("Document deleted sucessfully");
}
- } catch (LockException e) {
- LOG.error("Resource is locked.", e);
- transact.abort(txn);
-
- } catch (EXistException e) {
+ } catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
+ throw new HandeMessageException(e.getMessage(), e);
- } catch (TriggerException e) {
- LOG.error(e);
- transact.abort(txn);
-
- } catch (PermissionDeniedException e) {
- LOG.error(e);
- transact.abort(txn);
-
} finally {
// TODO: check if can be done earlier
@@ -385,6 +410,9 @@
}
}
+ /**
+ * Remove collection from database
+ */
private void deleteCollection(eXistMessage em) {
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
@@ -421,22 +449,11 @@
}
- } catch (EXistException e) {
+ } catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
+ throw new HandeMessageException(e.getMessage());
- } catch (IOException e) {
- LOG.error(e);
- transact.abort(txn);
-
- } catch (PermissionDeniedException e) {
- LOG.error(e);
- transact.abort(txn);
-
- } catch (TriggerException e) {
- LOG.error(e);
- transact.abort(txn);
-
} finally {
// TODO: check if can be done earlier
@@ -452,6 +469,9 @@
}
}
+ /**
+ * Created collection in database
+ */
private void createCollection(eXistMessage em) {
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
@@ -469,16 +489,13 @@
// TODO get user
broker = brokerPool.get(brokerPool.getSecurityManager().getSystemSubject());
- // Check if collection exists. not likely to happen since availability is
- // checked by ResourceFactory
+ // TODO ... consider to swallow situation transparently
collection = broker.openCollection(sourcePath, Lock.WRITE_LOCK);
if (collection != null) {
-
- LOG.debug("Collection already exists");
-
+ String errorText="Collection " + sourcePath + " already exists";
+ LOG.debug(errorText);
transact.abort(txn);
- // todo handle or ignore
- //throw new CollectionExistsException("Collection already exists");
+ throw new HandeMessageException(errorText);
}
// Create collection
@@ -493,25 +510,10 @@
LOG.debug("Collection created sucessfully");
}
-
- } catch (EXistException e) {
- LOG.error(e);
- transact.abort(txn);
-// throw e;
-
- } catch (IOException e) {
- LOG.error(e);
- transact.abort(txn);
-
- } catch (PermissionDeniedException e) {
- LOG.error(e);
- transact.abort(txn);
-// throw e;
-
} catch (Throwable e) {
LOG.error(e);
transact.abort(txn);
-// throw new EXistException(e);
+ throw new HandeMessageException(e.getMessage(), e);
} finally {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-31 15:05:01
|
Revision: 16512
http://exist.svn.sourceforge.net/exist/?rev=16512&view=rev
Author: shabanovd
Date: 2012-05-31 15:04:50 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] avoid NPE
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/AbstractGroup.java
Modified: trunk/eXist/src/org/exist/security/AbstractGroup.java
===================================================================
--- trunk/eXist/src/org/exist/security/AbstractGroup.java 2012-05-31 08:27:00 UTC (rev 16511)
+++ trunk/eXist/src/org/exist/security/AbstractGroup.java 2012-05-31 15:04:50 UTC (rev 16512)
@@ -100,7 +100,8 @@
@Override
public boolean isManager(Account account) {
for (Reference<SecurityManager, Account> manager : managers) {
- if (manager.resolve().equals(account))
+ Account acc = manager.resolve();
+ if (acc != null && acc.equals(account))
return true;
}
return false;
@@ -160,7 +161,9 @@
List<Account> list = new ArrayList<Account>(managers.size());
for (Reference<SecurityManager, Account> ref : managers) {
- list.add(ref.resolve());
+ Account acc = ref.resolve();
+ if (acc != null)
+ list.add(acc);
}
return list;
@@ -174,7 +177,8 @@
assertCanModifyGroup(subject);
for(Reference<SecurityManager, Account> ref : managers) {
- if(ref.resolve().getName().equals(account.getName())) {
+ Account acc = ref.resolve();
+ if(acc.getName().equals(account.getName())) {
managers.remove(ref);
break;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-31 08:27:11
|
Revision: 16511
http://exist.svn.sourceforge.net/exist/?rev=16511&view=rev
Author: shabanovd
Date: 2012-05-31 08:27:00 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[patch] Spatial Index:Overuse of PreparedStatement (thanks to Daniel Tremblay)
Modified Paths:
--------------
trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/AbstractGMLJDBCIndexWorker.java
trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/GMLHSQLIndexWorker.java
Modified: trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/AbstractGMLJDBCIndexWorker.java
===================================================================
--- trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/AbstractGMLJDBCIndexWorker.java 2012-05-31 07:25:12 UTC (rev 16510)
+++ trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/AbstractGMLJDBCIndexWorker.java 2012-05-31 08:27:00 UTC (rev 16511)
@@ -82,6 +82,7 @@
import java.io.IOException;
import java.io.StringReader;
import java.sql.Connection;
+import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;
@@ -275,6 +276,7 @@
if (conn != null) {
conn.setAutoCommit(true);
releaseConnection(conn);
+ //geometries.clear();
}
} catch (SQLException e) {
LOG.error(e);
@@ -285,13 +287,56 @@
private void saveDocumentNodes(Connection conn) throws SQLException {
if (geometries.size() == 0)
return;
+
+ PreparedStatement ps = conn.prepareStatement("INSERT INTO " + GMLHSQLIndex.TABLE_NAME + "(" +
+ /*1*/ "DOCUMENT_URI, " +
+ /*2*/ "NODE_ID_UNITS, " +
+ /*3*/ "NODE_ID, " +
+ /*4*/ "GEOMETRY_TYPE, " +
+ /*5*/ "SRS_NAME, " +
+ /*6*/ "WKT, " +
+ /*7*/ "WKB, " +
+ /*8*/ "MINX, " +
+ /*9*/ "MAXX, " +
+ /*10*/ "MINY, " +
+ /*11*/ "MAXY, " +
+ /*12*/ "CENTROID_X, " +
+ /*13*/ "CENTROID_Y, " +
+ /*14*/ "AREA, " +
+ //Boundary ?
+ /*15*/ "EPSG4326_WKT, " +
+ /*16*/ "EPSG4326_WKB, " +
+ /*17*/ "EPSG4326_MINX, " +
+ /*18*/ "EPSG4326_MAXX, " +
+ /*19*/ "EPSG4326_MINY, " +
+ /*20*/ "EPSG4326_MAXY, " +
+ /*21*/ "EPSG4326_CENTROID_X, " +
+ /*22*/ "EPSG4326_CENTROID_Y, " +
+ /*23*/ "EPSG4326_AREA," +
+ //Boundary ?
+ /*24*/ "IS_CLOSED, " +
+ /*25*/ "IS_SIMPLE, " +
+ /*26*/ "IS_VALID" +
+ ") VALUES (" +
+ "?, ?, ?, ?, ?, " +
+ "?, ?, ?, ?, ?, " +
+ "?, ?, ?, ?, ?, " +
+ "?, ?, ?, ?, ?, " +
+ "?, ?, ?, ?, ?, " +
+ "?"
+ + ")"
+ );
+
try {
- for (Map.Entry<NodeId, SRSGeometry> entry : geometries.entrySet()) {
- NodeId nodeId = entry.getKey();
- SRSGeometry srsGeometry = entry.getValue();
+ NodeId nodeId = null;
+ SRSGeometry srsGeometry = null;
+ for (Map.Entry<NodeId, SRSGeometry> entry : geometries.entrySet()) {
+ nodeId = entry.getKey();
+ srsGeometry = entry.getValue();
+
try {
saveGeometryNode(srsGeometry.getGeometry(), srsGeometry.getSRSName(),
- currentDoc, nodeId, conn);
+ currentDoc, nodeId, ps);
} finally {
//Help the garbage collector
srsGeometry = null;
@@ -299,6 +344,10 @@
}
} finally {
geometries.clear();
+ if (ps != null) {
+ ps.close();
+ ps = null;
+ }
}
}
@@ -477,7 +526,7 @@
}
}
- protected abstract boolean saveGeometryNode(Geometry geometry, String srsName, DocumentImpl doc, NodeId nodeId, Connection conn) throws SQLException;
+ protected abstract boolean saveGeometryNode(Geometry geometry, String srsName, DocumentImpl doc, NodeId nodeId, PreparedStatement ps) throws SQLException;
protected abstract boolean removeDocumentNode(DocumentImpl doc, NodeId nodeID, Connection conn) throws SQLException;
Modified: trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/GMLHSQLIndexWorker.java
===================================================================
--- trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/GMLHSQLIndexWorker.java 2012-05-31 07:25:12 UTC (rev 16510)
+++ trunk/eXist/extensions/indexes/spatial/src/org/exist/indexing/spatial/GMLHSQLIndexWorker.java 2012-05-31 08:27:00 UTC (rev 16511)
@@ -76,45 +76,7 @@
}
@Override
- protected boolean saveGeometryNode(Geometry geometry, String srsName, DocumentImpl doc, NodeId nodeId, Connection conn) throws SQLException {
- PreparedStatement ps = conn.prepareStatement("INSERT INTO " + GMLHSQLIndex.TABLE_NAME + "(" +
- /*1*/ "DOCUMENT_URI, " +
- /*2*/ "NODE_ID_UNITS, " +
- /*3*/ "NODE_ID, " +
- /*4*/ "GEOMETRY_TYPE, " +
- /*5*/ "SRS_NAME, " +
- /*6*/ "WKT, " +
- /*7*/ "WKB, " +
- /*8*/ "MINX, " +
- /*9*/ "MAXX, " +
- /*10*/ "MINY, " +
- /*11*/ "MAXY, " +
- /*12*/ "CENTROID_X, " +
- /*13*/ "CENTROID_Y, " +
- /*14*/ "AREA, " +
- //Boundary ?
- /*15*/ "EPSG4326_WKT, " +
- /*16*/ "EPSG4326_WKB, " +
- /*17*/ "EPSG4326_MINX, " +
- /*18*/ "EPSG4326_MAXX, " +
- /*19*/ "EPSG4326_MINY, " +
- /*20*/ "EPSG4326_MAXY, " +
- /*21*/ "EPSG4326_CENTROID_X, " +
- /*22*/ "EPSG4326_CENTROID_Y, " +
- /*23*/ "EPSG4326_AREA," +
- //Boundary ?
- /*24*/ "IS_CLOSED, " +
- /*25*/ "IS_SIMPLE, " +
- /*26*/ "IS_VALID" +
- ") VALUES (" +
- "?, ?, ?, ?, ?, " +
- "?, ?, ?, ?, ?, " +
- "?, ?, ?, ?, ?, " +
- "?, ?, ?, ?, ?, " +
- "?, ?, ?, ?, ?, " +
- "?"
- + ")"
- );
+ protected boolean saveGeometryNode(Geometry geometry, String srsName, DocumentImpl doc, NodeId nodeId, PreparedStatement ps) throws SQLException {
try {
Geometry EPSG4326_geometry = null;
try {
@@ -125,6 +87,8 @@
ee.initCause(e);
throw ee;
}
+ ps.clearParameters();
+
/*DOCUMENT_URI*/ ps.setString(1, doc.getURI().toString());
/*NODE_ID_UNITS*/ ps.setInt(2, nodeId.units());
byte[] bytes = new byte[nodeId.size()];
@@ -163,10 +127,9 @@
/*IS_VALID*/ ps.setBoolean(26, geometry.isValid());
return (ps.executeUpdate() == 1);
} finally {
- if (ps != null)
- ps.close();
//Let's help the garbage collector...
geometry = null;
+ ps.clearParameters();
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-31 07:25:19
|
Revision: 16510
http://exist.svn.sourceforge.net/exist/?rev=16510&view=rev
Author: shabanovd
Date: 2012-05-31 07:25:12 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] cleanup
Modified Paths:
--------------
trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
trunk/eXist/src/org/exist/security/AbstractRealm.java
trunk/eXist/src/org/exist/security/realm/Realm.java
Modified: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
===================================================================
--- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-31 07:07:46 UTC (rev 16509)
+++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-31 07:25:12 UTC (rev 16510)
@@ -606,26 +606,26 @@
}
}
- public final synchronized Group getGroup(LdapContext ctx, String name) {
+ public final synchronized Group getGroup(LdapContext ctx, final String name) {
if (name == null) return null;
- name = ensureCase(name);
+ String gName = ensureCase(name);
- Group grp = getGroup(name);
+ Group grp = getGroup(gName);
if(grp != null) {
return grp;
} else {
//if the group is not cached, we should try and find it in LDAP and cache it if it exists
try {
//do the lookup
- SearchResult ldapGroup = findGroupByGroupName(ctx, removeDomainPostfix(name));
+ SearchResult ldapGroup = findGroupByGroupName(ctx, removeDomainPostfix(gName));
if(ldapGroup == null) {
return null;
} else {
//found a group from ldap so cache them and return
try {
- return createGroupInDatabase(name);
+ return createGroupInDatabase(gName);
//registerGroup(grp); //TODO do we need to do this?
} catch(AuthenticationException ae) {
LOG.error(ae.getMessage(), ae);
@@ -642,7 +642,6 @@
}
}
}
-
private String addDomainPostfix(String principalName) {
String name = principalName;
@@ -672,10 +671,10 @@
private boolean checkPrincipalRestrictionList(String principalName, AbstractLDAPSearchPrincipal searchPrinciple) {
- principalName = ensureCase(principalName);
+ String name = ensureCase(principalName);
- if(principalName.indexOf('@') > -1) {
- principalName = principalName.substring(0, principalName.indexOf('@'));
+ if(name.indexOf('@') > -1) {
+ name = name.substring(0, name.indexOf('@'));
}
List<String> blackList = null;
@@ -690,7 +689,7 @@
if(blackList != null) {
for(String blackEntry : blackList) {
- if(ensureCase(blackEntry).equals(principalName)) {
+ if(ensureCase(blackEntry).equals(name)) {
return false;
}
}
@@ -698,7 +697,7 @@
if(whiteList != null && whiteList.size() > 0) {
for(String whiteEntry : whiteList) {
- if(ensureCase(whiteEntry).equals(principalName)) {
+ if(ensureCase(whiteEntry).equals(name)) {
return true;
}
}
@@ -790,6 +789,7 @@
return searchResult;
}
}
+ LOG.error("Matched no groups for the groupName: " + groupName);
return null;
}
@@ -823,7 +823,7 @@
@Override
public boolean deleteGroup(Group group) throws PermissionDeniedException, EXistException {
- // TODO Auto-generated method stub
+ //XXX: delete local cache?
return false;
}
@@ -931,9 +931,9 @@
}
@Override
- public List<String> findUsernamesWhereNamePartStarts(String startsWith) {
+ public List<String> findUsernamesWhereNamePartStarts(final String startsWith) {
- startsWith = ensureCase(startsWith);
+ String sWith = ensureCase(startsWith);
List<String> usernames = new ArrayList<String>();
@@ -943,8 +943,8 @@
LDAPSearchContext search = ensureContextFactory().getSearch();
- SearchAttribute firstNameSa = new SearchAttribute(search.getSearchAccount().getMetadataSearchAttribute(AXSchemaType.FIRSTNAME), startsWith + "*");
- SearchAttribute lastNameSa = new SearchAttribute(search.getSearchAccount().getMetadataSearchAttribute(AXSchemaType.LASTNAME), startsWith + "*");
+ SearchAttribute firstNameSa = new SearchAttribute(search.getSearchAccount().getMetadataSearchAttribute(AXSchemaType.FIRSTNAME), sWith + "*");
+ SearchAttribute lastNameSa = new SearchAttribute(search.getSearchAccount().getMetadataSearchAttribute(AXSchemaType.LASTNAME), sWith + "*");
List<SearchAttribute> sas = new ArrayList<SearchAttribute>();
sas.add(firstNameSa);
sas.add(lastNameSa);
@@ -977,9 +977,9 @@
}
@Override
- public List<String> findUsernamesWhereUsernameStarts(String startsWith) {
+ public List<String> findUsernamesWhereUsernameStarts(final String startsWith) {
- startsWith = ensureCase(startsWith);
+ String sWith = ensureCase(startsWith);
List<String> usernames = new ArrayList<String>();
@@ -988,7 +988,7 @@
ctx = getContext(getSecurityManager().getCurrentSubject());
LDAPSearchContext search = ensureContextFactory().getSearch();
- SearchAttribute sa = new SearchAttribute(search.getSearchAccount().getSearchAttribute(LDAPSearchAttributeKey.NAME), startsWith + "*");
+ SearchAttribute sa = new SearchAttribute(search.getSearchAccount().getSearchAttribute(LDAPSearchAttributeKey.NAME), sWith + "*");
String searchFilter = buildSearchFilter(search.getSearchAccount().getSearchFilterPrefix(), sa);
SearchControls searchControls = new SearchControls();
@@ -1055,9 +1055,9 @@
}
@Override
- public List<String> findGroupnamesWhereGroupnameStarts(String startsWith) {
+ public List<String> findGroupnamesWhereGroupnameStarts(final String startsWith) {
- startsWith = ensureCase(startsWith);
+ String sWith = ensureCase(startsWith);
List<String> groupnames = new ArrayList<String>();
@@ -1066,7 +1066,7 @@
ctx = getContext(getSecurityManager().getCurrentSubject());
LDAPSearchContext search = ensureContextFactory().getSearch();
- SearchAttribute sa = new SearchAttribute(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.NAME), startsWith + "*");
+ SearchAttribute sa = new SearchAttribute(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.NAME), sWith + "*");
String searchFilter = buildSearchFilter(search.getSearchGroup().getSearchFilterPrefix(), sa);
SearchControls searchControls = new SearchControls();
@@ -1096,9 +1096,9 @@
}
@Override
- public List<String> findGroupnamesWhereGroupnameContains(String fragment) {
+ public List<String> findGroupnamesWhereGroupnameContains(final String fragment) {
- fragment = ensureCase(fragment);
+ String part = ensureCase(fragment);
List<String> groupnames = new ArrayList<String>();
@@ -1107,7 +1107,7 @@
ctx = getContext(getSecurityManager().getCurrentSubject());
LDAPSearchContext search = ensureContextFactory().getSearch();
- SearchAttribute sa = new SearchAttribute(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.NAME), "*" + fragment + "*");
+ SearchAttribute sa = new SearchAttribute(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.NAME), "*" + part + "*");
String searchFilter = buildSearchFilter(search.getSearchGroup().getSearchFilterPrefix(), sa);
SearchControls searchControls = new SearchControls();
@@ -1126,7 +1126,7 @@
}
}
} catch(NamingException ne) {
- LOG.error(new AuthenticationException(AuthenticationException.UNNOWN_EXCEPTION, ne.getMessage()));
+ LOG.error(ne);
} finally {
if(ctx != null) {
LdapUtils.closeContext(ctx);
@@ -1174,13 +1174,13 @@
}
@Override
- public List<String> findAllGroupMembers(String groupName) {
+ public List<String> findAllGroupMembers(final String groupName) {
- groupName = ensureCase(groupName);
+ String name = ensureCase(groupName);
List<String> groupMembers = new ArrayList<String>();
- if(!checkGroupRestrictionList(groupName)) {
+ if(!checkGroupRestrictionList(name)) {
return groupMembers;
}
@@ -1189,7 +1189,7 @@
ctx = getContext(getSecurityManager().getCurrentSubject());
//find the dn of the group
- SearchResult searchResult = findGroupByGroupName(ctx, removeDomainPostfix(groupName));
+ SearchResult searchResult = findGroupByGroupName(ctx, removeDomainPostfix(name));
LDAPSearchContext search = ensureContextFactory().getSearch();
String dnGroup = (String)searchResult.getAttributes().get(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.DN)).get();
Modified: trunk/eXist/src/org/exist/security/AbstractRealm.java
===================================================================
--- trunk/eXist/src/org/exist/security/AbstractRealm.java 2012-05-31 07:07:46 UTC (rev 16509)
+++ trunk/eXist/src/org/exist/security/AbstractRealm.java 2012-05-31 07:25:12 UTC (rev 16510)
@@ -85,7 +85,7 @@
return sm;
}
- protected void initialiseRealmStorage(DBBroker broker) throws EXistException {
+ protected void initialiseRealmStorage(final DBBroker broker) throws EXistException {
final XmldbURI realmCollectionURL = SecurityManager.SECURITY_COLLECTION_URI.append(getId());
@@ -105,16 +105,16 @@
} catch(PermissionDeniedException pde) {
transact.abort(txn);
- throw new EXistException(pde.getMessage(), pde);
+ throw new EXistException(pde);
} catch(IOException ioe) {
transact.abort(txn);
- throw new EXistException(ioe.getMessage(), ioe);
+ throw new EXistException(ioe);
} catch(LockException le) {
transact.abort(txn);
- throw new EXistException(le.getMessage(), le);
+ throw new EXistException(le);
} catch(TriggerException te) {
transact.abort(txn);
- throw new EXistException(te.getMessage(), te);
+ throw new EXistException(te);
}
}
@@ -151,7 +151,7 @@
}
}
- private void loadRemovedGroupsFromRealmStorage(DBBroker broker) throws ConfigurationException, PermissionDeniedException, LockException {
+ private void loadRemovedGroupsFromRealmStorage(final DBBroker broker) throws ConfigurationException, PermissionDeniedException, LockException {
//load marked for remove groups information
if (collectionRemovedGroups != null && collectionRemovedGroups.getDocumentCount(broker) > 0) {
for(Iterator<DocumentImpl> i = collectionRemovedGroups.iterator(broker); i.hasNext(); ) {
@@ -201,7 +201,7 @@
}
}
- private void loadRemovedAccountsFromRealmStorage(DBBroker broker) throws ConfigurationException, PermissionDeniedException, LockException {
+ private void loadRemovedAccountsFromRealmStorage(final DBBroker broker) throws ConfigurationException, PermissionDeniedException, LockException {
//load marked for remove accounts information
if (collectionRemovedAccounts != null && collectionRemovedAccounts.getDocumentCount(broker) > 0) {
for(Iterator<DocumentImpl> i = collectionRemovedAccounts.iterator(broker); i.hasNext(); ) {
@@ -222,7 +222,7 @@
@Override
- public void startUp(DBBroker broker) throws EXistException {
+ public void startUp(final DBBroker broker) throws EXistException {
initialiseRealmStorage(broker);
@@ -233,9 +233,9 @@
loadAccountsFromRealmStorage(broker);
loadRemovedAccountsFromRealmStorage(broker);
} catch(PermissionDeniedException pde) {
- throw new EXistException(pde.getMessage(), pde);
+ throw new EXistException(pde);
} catch(LockException le) {
- throw new EXistException(le.getMessage(), le);
+ throw new EXistException(le);
}
}
@@ -453,7 +453,7 @@
}
@Override
- public Group getExternalGroup(String name) {
+ public Group getExternalGroup(final String name) {
return getSecurityManager().getGroup(name);
}
@@ -550,12 +550,12 @@
}
@Override
- public List<String> findUsernamesWhereNameStarts(String startsWith) {
+ public List<String> findUsernamesWhereNameStarts(final String startsWith) {
return new ArrayList<String>();
}
@Override
- public List<String> findUsernamesWhereUsernameStarts(String startsWith) {
+ public List<String> findUsernamesWhereUsernameStarts(final String startsWith) {
return new ArrayList<String>();
}
@@ -565,22 +565,22 @@
}
@Override
- public List<String> findAllGroupMembers(String groupName) {
+ public List<String> findAllGroupMembers(final String groupName) {
return new ArrayList<String>();
}
@Override
- public List<String> findUsernamesWhereNamePartStarts(String startsWith) {
+ public List<String> findUsernamesWhereNamePartStarts(final String startsWith) {
return new ArrayList<String>();
}
@Override
- public java.util.Collection<? extends String> findGroupnamesWhereGroupnameStarts(String startsWith) {
+ public java.util.Collection<? extends String> findGroupnamesWhereGroupnameStarts(final String startsWith) {
return new ArrayList<String>();
}
@Override
- public java.util.Collection<? extends String> findGroupnamesWhereGroupnameContains(String fragment) {
+ public java.util.Collection<? extends String> findGroupnamesWhereGroupnameContains(final String fragment) {
return new ArrayList<String>();
}
}
\ No newline at end of file
Modified: trunk/eXist/src/org/exist/security/realm/Realm.java
===================================================================
--- trunk/eXist/src/org/exist/security/realm/Realm.java 2012-05-31 07:07:46 UTC (rev 16509)
+++ trunk/eXist/src/org/exist/security/realm/Realm.java 2012-05-31 07:25:12 UTC (rev 16510)
@@ -29,7 +29,6 @@
import org.exist.config.Startable;
import org.exist.security.Group;
import org.exist.security.Account;
-import org.exist.security.Subject;
import org.exist.security.SecurityManager;
import org.exist.security.management.AccountsManagement;
import org.exist.security.management.GroupsManagement;
@@ -55,13 +54,13 @@
public Database getDatabase();
- public Group getExternalGroup(String name);
+ public Group getExternalGroup(final String name);
public List<String> findUsernamesWhereNameStarts(String startsWith);
public List<String> findUsernamesWhereNamePartStarts(String startsWith);
public List<String> findUsernamesWhereUsernameStarts(String startsWith);
public List<String> findAllGroupNames();
- public List<String> findAllGroupMembers(String groupName);
+ public List<String> findAllGroupMembers(final String groupName);
public SecurityManager getSecurityManager();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-31 07:07:52
|
Revision: 16509
http://exist.svn.sourceforge.net/exist/?rev=16509&view=rev
Author: shabanovd
Date: 2012-05-31 07:07:46 +0000 (Thu, 31 May 2012)
Log Message:
-----------
[ignore] DBA or group manager can delete group
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/internal/RealmImpl.java
trunk/eXist/src/org/exist/xmldb/LocalUserManagementService.java
trunk/eXist/src/org/exist/xquery/functions/securitymanager/DeleteGroupFunction.java
Modified: trunk/eXist/src/org/exist/security/internal/RealmImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-30 21:15:42 UTC (rev 16508)
+++ trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-31 07:07:46 UTC (rev 16509)
@@ -209,60 +209,40 @@
@Override
public boolean deleteGroup(final Group group) throws PermissionDeniedException, EXistException {
- if(group == null) {
+ if(group == null)
return false;
- }
groupsByName.modify2E(new PrincipalDbModify2E<Group, PermissionDeniedException, EXistException>(){
@Override
public void execute(Map<String, Group> principalDb) throws PermissionDeniedException, EXistException {
AbstractPrincipal remove_group = (AbstractPrincipal)principalDb.get(group.getName());
- if(remove_group == null) {
- throw new IllegalArgumentException("Group does not exist!");
- }
+ if(remove_group == null)
+ throw new IllegalArgumentException("Group does '"+group.getName()+"' not exist!");
- DBBroker broker = null;
- try {
- broker = getDatabase().get(null);
- Subject subject = broker.getSubject();
-
- Group g = (Group)remove_group;
- if (
- !(
- (
- (g.isManager(subject) && g.getManagers().size() == 1)
- || subject.hasDbaRole()
- )
- )
- ) {
- throw new PermissionDeniedException(
- "Account '"+subject.getName()+"' can not delete a group '"+remove_group.getName()+"'.");
- }
+ DBBroker broker = getDatabase().getActiveBroker();
+ Subject subject = broker.getSubject();
+
+ ((Group)remove_group).assertCanModifyGroup(subject);
+
+ remove_group.setRemoved(true);
+ remove_group.setCollection(broker, collectionRemovedGroups, XmldbURI.create(UUIDGenerator.getUUID() + ".xml"));
+
+ TransactionManager transaction = getDatabase().getTransactionManager();
+ Txn txn = null;
+ try {
+ txn = transaction.beginTransaction();
- remove_group.setRemoved(true);
- remove_group.setCollection(broker, collectionRemovedGroups, XmldbURI.create(UUIDGenerator.getUUID() + ".xml"));
-
- TransactionManager transaction = getDatabase().getTransactionManager();
- Txn txn = null;
- try {
- txn = transaction.beginTransaction();
-
- collectionGroups.removeXMLResource(txn, broker, XmldbURI.create(remove_group.getName() + ".xml" ));
+ collectionGroups.removeXMLResource(txn, broker, XmldbURI.create(remove_group.getName() + ".xml" ));
- transaction.commit(txn);
- } catch (Exception e) {
- transaction.abort(txn);
- e.printStackTrace();
- LOG.debug("loading configuration failed: " + e.getMessage());
- }
-
- getSecurityManager().addGroup(remove_group.getId(), (Group)remove_group);
- principalDb.remove(remove_group.getName());
-
- } finally {
- getDatabase().release(broker);
- }
+ transaction.commit(txn);
+ } catch (Exception e) {
+ transaction.abort(txn);
+ LOG.debug(e);
+ }
+
+ getSecurityManager().addGroup(remove_group.getId(), (Group)remove_group);
+ principalDb.remove(remove_group.getName());
}
});
@@ -294,17 +274,6 @@
}
@Override
- public List<String> findUsernamesWhereNameStarts(String startsWith) {
- return new ArrayList<String>(); //TODO at present exist users cannot have personal name details
- }
-
- @Override
- public List<String> findUsernamesWhereNamePartStarts(String startsWith) {
- return new ArrayList<String>(); //TODO at present exist users cannot have personal name details
- }
-
-
- @Override
public List<String> findUsernamesWhereUsernameStarts(final String startsWith) {
return usersByName.read(new PrincipalDbRead<Account, List<String>>(){
@@ -379,4 +348,14 @@
}
});
}
+
+ @Override
+ public List<String> findUsernamesWhereNameStarts(String startsWith) {
+ return new ArrayList<String>(); //TODO at present exist users cannot have personal name details
+ }
+
+ @Override
+ public List<String> findUsernamesWhereNamePartStarts(String startsWith) {
+ return new ArrayList<String>(); //TODO at present exist users cannot have personal name details
+ }
}
\ No newline at end of file
Modified: trunk/eXist/src/org/exist/xmldb/LocalUserManagementService.java
===================================================================
--- trunk/eXist/src/org/exist/xmldb/LocalUserManagementService.java 2012-05-30 21:15:42 UTC (rev 16508)
+++ trunk/eXist/src/org/exist/xmldb/LocalUserManagementService.java 2012-05-31 07:07:46 UTC (rev 16509)
@@ -706,13 +706,9 @@
public void removeGroup(final Group group) throws XMLDBException {
try {
executeWithBroker(new BrokerOperation<Void>(){
-
@Override
public Void withBroker(DBBroker broker) throws XMLDBException, LockException, PermissionDeniedException, IOException, EXistException, TriggerException, SyntaxException {
SecurityManager sm = broker.getBrokerPool().getSecurityManager();
- if(!sm.hasAdminPrivileges(user)) {
- throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "you are not allowed to remove groups");
- }
sm.deleteGroup(group.getName());
Modified: trunk/eXist/src/org/exist/xquery/functions/securitymanager/DeleteGroupFunction.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/functions/securitymanager/DeleteGroupFunction.java 2012-05-30 21:15:42 UTC (rev 16508)
+++ trunk/eXist/src/org/exist/xquery/functions/securitymanager/DeleteGroupFunction.java 2012-05-31 07:07:46 UTC (rev 16509)
@@ -55,10 +55,7 @@
Subject currentSubject = context.getBroker().getSubject();
try {
- final Group group = sm.getGroup(args[0].itemAt(0).getStringValue());
- if(group.isManager(currentSubject)) {
- throw new PermissionDeniedException("Only a group manager may delete a group");
- }
+ final String name = args[0].itemAt(0).getStringValue();
final Group successorGroup;
if(getArgumentCount() == 2) {
@@ -69,14 +66,14 @@
successorGroup = sm.getGroup(successorGroupName);
} else {
- successorGroup = sm.getGroup("guest");
+ successorGroup = sm.getGroup("guest");
}
//TODO how to handle user which are members of this group
//also how to reassign resources that are allocated to this group to another group
try {
- sm.deleteGroup(group.getName());
+ sm.deleteGroup(name);
} catch(EXistException ee) {
throw new XPathException(this, ee);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-30 21:15:48
|
Revision: 16508
http://exist.svn.sourceforge.net/exist/?rev=16508&view=rev
Author: dizzzz
Date: 2012-05-30 21:15:42 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[ignore] refactoring, add work notes. Base function works, need to add two more operations
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Added Paths:
-----------
branches/dizzzz/clustering/extensions/clustering/doc/TODO.txt
Property Changed:
----------------
branches/dizzzz/clustering/extensions/clustering/doc/
Property changes on: branches/dizzzz/clustering/extensions/clustering/doc
___________________________________________________________________
Added: svn:ignore
+ .TODO.txt.swp
Added: branches/dizzzz/clustering/extensions/clustering/doc/TODO.txt
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/doc/TODO.txt (rev 0)
+++ branches/dizzzz/clustering/extensions/clustering/doc/TODO.txt 2012-05-30 21:15:42 UTC (rev 16508)
@@ -0,0 +1,9 @@
+ToDo's
+
+- onMessage() should throw Runtime/unchecked exceptions in case of problems
+- listener.... if collection does not exist, throw exception, do not continue (NPE)
+
+- prevent infinite loop if node is sender and receiver
+-- write clientid to disk? (UUID)
+S
+- add more JMSmessage properties
\ No newline at end of file
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 19:15:25 UTC (rev 16507)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 21:15:42 UTC (rev 16508)
@@ -56,7 +56,7 @@
/**
* Constructor
- *
+ *
* @param brokerpool Database brokerpool
*/
public eXistJMSListener(BrokerPool brokerpool) {
@@ -64,8 +64,8 @@
}
/**
- * COnvert JMS ByteMessage into an eXist-db specific message.
- *
+ * Convert JMS ByteMessage into an eXist-db specific message.
+ *
* @param bm The original message
* @return The converted message
*/
@@ -86,8 +86,8 @@
value = bm.getStringProperty(eXistMessage.EXIST_PATH_DESTINATION);
em.setDestinationPath(value);
-
+
// This is potentially memory intensive
long size = bm.getBodyLength();
byte[] payload = new byte[(int) size];
@@ -104,7 +104,7 @@
@Override
public void onMessage(Message msg) {
-
+
if (msg instanceof BytesMessage) {
BytesMessage bm = (BytesMessage) msg;
@@ -139,8 +139,8 @@
}
/**
- * Handle operation on documents
- *
+ * Handle operation on documents
+ *
* @param em Message containing information about documents
*/
private void handleDocument(eXistMessage em) {
@@ -167,10 +167,9 @@
}
}
-
/**
- * Handle operation on collections
- *
+ * Handle operation on collections
+ *
* @param em Message containing information about collections
*/
private void handleCollection(eXistMessage em) {
@@ -249,15 +248,16 @@
VirtualTempFile vtf = new VirtualTempFile(em.getPayload());
VirtualTempFileInputSource vt = new VirtualTempFileInputSource(vtf);
InputStream bis = vt.getByteStream();
-
+
GZIPInputStream gis = new GZIPInputStream(bis);
InputSource is = new InputSource(gis);
-
+
IndexInfo info = collection.validateXMLResource(txn, broker, docURI, is);
DocumentImpl doc = info.getDocument();
doc.getMetadata().setMimeType(mime.getName());
- bis.reset();
+ // reconstruct gzip input stream
+ bis.reset();
gis = new GZIPInputStream(bis);
is = new InputSource(gis);
@@ -290,7 +290,7 @@
} catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
transact.abort(txn);
-
+
} finally {
// TODO: check if can be done earlier
@@ -300,13 +300,14 @@
brokerPool.release(broker);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Finished creation");
+ }
}
}
private void deleteDocument(eXistMessage em) {
-
+
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
XmldbURI colURI = sourcePath.removeLastSegment();
XmldbURI docURI = sourcePath.lastSegment();
@@ -341,7 +342,7 @@
if (resource.getResourceType() == DocumentImpl.BINARY_FILE) {
collection.removeBinaryResource(txn, broker, resource.getFileURI());
-
+
} else {
collection.removeXMLResource(txn, broker, resource.getFileURI());
}
@@ -349,8 +350,9 @@
// Commit change
transact.commit(txn);
- if(LOG.isDebugEnabled())
- LOG.debug("Document deleted sucessfully");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Document deleted sucessfully");
+ }
} catch (LockException e) {
LOG.error("Resource is locked.", e);
@@ -377,18 +379,19 @@
brokerPool.release(broker);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Finished delete");
+ }
}
}
private void deleteCollection(eXistMessage em) {
-
+
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
XmldbURI colURI = sourcePath.removeLastSegment();
XmldbURI docURI = sourcePath.lastSegment();
-
+
DBBroker broker = null;
Collection collection = null;
@@ -413,8 +416,9 @@
// Commit change
transact.commit(txn);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Document deleted sucessfully");
+ }
} catch (EXistException e) {
@@ -433,7 +437,7 @@
LOG.error(e);
transact.abort(txn);
- } finally {
+ } finally {
// TODO: check if can be done earlier
if (collection != null) {
@@ -442,13 +446,14 @@
brokerPool.release(broker);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Finished delete");
+ }
}
}
private void createCollection(eXistMessage em) {
-
+
XmldbURI sourcePath = XmldbURI.create(em.getResourcePath());
XmldbURI colURI = sourcePath.removeLastSegment();
XmldbURI docURI = sourcePath.lastSegment();
@@ -470,7 +475,7 @@
if (collection != null) {
LOG.debug("Collection already exists");
-
+
transact.abort(txn);
// todo handle or ignore
//throw new CollectionExistsException("Collection already exists");
@@ -484,8 +489,9 @@
// Commit change
transact.commit(txn);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Collection created sucessfully");
+ }
} catch (EXistException e) {
@@ -516,8 +522,9 @@
brokerPool.release(broker);
- if(LOG.isDebugEnabled())
+ if (LOG.isDebugEnabled()) {
LOG.debug("Finished creation");
+ }
}
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-30 19:15:31
|
Revision: 16507
http://exist.svn.sourceforge.net/exist/?rev=16507&view=rev
Author: dizzzz
Date: 2012-05-30 19:15:25 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[ignore] XML documents now endup right into database; cleanup needed
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 18:04:22 UTC (rev 16506)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 19:15:25 UTC (rev 16507)
@@ -246,11 +246,7 @@
}
// Stream into database
-// ByteArrayInputStream bais = new ByteArrayInputStream(em.getPayload());
-
VirtualTempFile vtf = new VirtualTempFile(em.getPayload());
-// InputStream bis = vtf.getByteStream();
-
VirtualTempFileInputSource vt = new VirtualTempFileInputSource(vtf);
InputStream bis = vt.getByteStream();
@@ -260,6 +256,11 @@
IndexInfo info = collection.validateXMLResource(txn, broker, docURI, is);
DocumentImpl doc = info.getDocument();
doc.getMetadata().setMimeType(mime.getName());
+
+ bis.reset();
+ gis = new GZIPInputStream(bis);
+ is = new InputSource(gis);
+
collection.store(txn, broker, info, is, false);
is.getByteStream().close();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <di...@us...> - 2012-05-30 18:04:32
|
Revision: 16506
http://exist.svn.sourceforge.net/exist/?rev=16506&view=rev
Author: dizzzz
Date: 2012-05-30 18:04:22 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[ignore] attempt to have XML documents distributed
Modified Paths:
--------------
branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
Modified: branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java
===================================================================
--- branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 17:46:04 UTC (rev 16505)
+++ branches/dizzzz/clustering/extensions/clustering/src/org/exist/clustering/triggers/receive/eXistJMSListener.java 2012-05-30 18:04:22 UTC (rev 16506)
@@ -249,9 +249,12 @@
// ByteArrayInputStream bais = new ByteArrayInputStream(em.getPayload());
VirtualTempFile vtf = new VirtualTempFile(em.getPayload());
- InputStream bis = vtf.getByteStream();
+// InputStream bis = vtf.getByteStream();
+
+ VirtualTempFileInputSource vt = new VirtualTempFileInputSource(vtf);
+ InputStream bis = vt.getByteStream();
+
GZIPInputStream gis = new GZIPInputStream(bis);
-
InputSource is = new InputSource(gis);
IndexInfo info = collection.validateXMLResource(txn, broker, docURI, is);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-30 17:46:15
|
Revision: 16505
http://exist.svn.sourceforge.net/exist/?rev=16505&view=rev
Author: shabanovd
Date: 2012-05-30 17:46:04 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[ignore] user can delete group only if user is single group manager
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/internal/RealmImpl.java
Modified: trunk/eXist/src/org/exist/security/internal/RealmImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-30 16:15:56 UTC (rev 16504)
+++ trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-30 17:46:04 UTC (rev 16505)
@@ -227,7 +227,15 @@
broker = getDatabase().get(null);
Subject subject = broker.getSubject();
- if (!(((Group)remove_group).isManager(subject) || subject.hasDbaRole())) {
+ Group g = (Group)remove_group;
+ if (
+ !(
+ (
+ (g.isManager(subject) && g.getManagers().size() == 1)
+ || subject.hasDbaRole()
+ )
+ )
+ ) {
throw new PermissionDeniedException(
"Account '"+subject.getName()+"' can not delete a group '"+remove_group.getName()+"'.");
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-30 16:16:07
|
Revision: 16504
http://exist.svn.sourceforge.net/exist/?rev=16504&view=rev
Author: shabanovd
Date: 2012-05-30 16:15:56 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[bugfix] not only DBA users should be able to delete group, but group's managers
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/internal/RealmImpl.java
Modified: trunk/eXist/src/org/exist/security/internal/RealmImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-30 09:46:47 UTC (rev 16503)
+++ trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-30 16:15:56 UTC (rev 16504)
@@ -217,18 +217,19 @@
@Override
public void execute(Map<String, Group> principalDb) throws PermissionDeniedException, EXistException {
- AbstractPrincipal remove_group = (AbstractPrincipal)principalDb.get(group.getName());
- if(remove_group == null) {
+ AbstractPrincipal remove_group = (AbstractPrincipal)principalDb.get(group.getName());
+ if(remove_group == null) {
throw new IllegalArgumentException("Group does not exist!");
}
- DBBroker broker = null;
- try {
+ DBBroker broker = null;
+ try {
broker = getDatabase().get(null);
Subject subject = broker.getSubject();
- if(!( subject.hasDbaRole())) {
- throw new PermissionDeniedException("You are not allowed to delete '" + remove_group.getName() + "' group");
+ if (!(((Group)remove_group).isManager(subject) || subject.hasDbaRole())) {
+ throw new PermissionDeniedException(
+ "Account '"+subject.getName()+"' can not delete a group '"+remove_group.getName()+"'.");
}
remove_group.setRemoved(true);
@@ -251,9 +252,9 @@
getSecurityManager().addGroup(remove_group.getId(), (Group)remove_group);
principalDb.remove(remove_group.getName());
- } finally {
+ } finally {
getDatabase().release(broker);
- }
+ }
}
});
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-30 09:46:58
|
Revision: 16503
http://exist.svn.sourceforge.net/exist/?rev=16503&view=rev
Author: shabanovd
Date: 2012-05-30 09:46:47 +0000 (Wed, 30 May 2012)
Log Message:
-----------
[ignore] avoid NPE
Modified Paths:
--------------
trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
trunk/eXist/src/org/exist/security/AbstractRealm.java
Modified: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
===================================================================
--- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-29 21:12:51 UTC (rev 16502)
+++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-30 09:46:47 UTC (rev 16503)
@@ -107,9 +107,11 @@
}
private String ensureCase(String username) {
- if(principalsAreCaseInsensitive) {
+ if (username == null) return null;
+
+ if (principalsAreCaseInsensitive)
return username.toLowerCase();
- }
+
return username;
}
@@ -605,6 +607,8 @@
}
public final synchronized Group getGroup(LdapContext ctx, String name) {
+
+ if (name == null) return null;
name = ensureCase(name);
@@ -756,6 +760,7 @@
return addDomainPostfix((String)searchResult.getAttributes().get(search.getSearchGroup().getSearchAttribute(LDAPSearchAttributeKey.NAME)).get());
}
}
+ LOG.error("Matched no group with SID: " + sid);
return null;
}
Modified: trunk/eXist/src/org/exist/security/AbstractRealm.java
===================================================================
--- trunk/eXist/src/org/exist/security/AbstractRealm.java 2012-05-29 21:12:51 UTC (rev 16502)
+++ trunk/eXist/src/org/exist/security/AbstractRealm.java 2012-05-30 09:46:47 UTC (rev 16503)
@@ -56,9 +56,6 @@
*/
public abstract class AbstractRealm implements Realm, Configurable {
- //XXX: this class must be under org.exist.security.internal to be protected
- //public final Map<String, Account> usersByName = new HashMap<String, Account>(65);
- //public final Map<String, Group> groupsByName = new HashMap<String, Group>(65);
protected final PrincipalDbByName<Account> usersByName = new PrincipalDbByName<Account>();
protected final PrincipalDbByName<Group> groupsByName = new PrincipalDbByName<Group>();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wol...@us...> - 2012-05-29 21:12:58
|
Revision: 16502
http://exist.svn.sourceforge.net/exist/?rev=16502&view=rev
Author: wolfgang_m
Date: 2012-05-29 21:12:51 +0000 (Tue, 29 May 2012)
Log Message:
-----------
Next (and final) iteration of the templating module: use XQuery annotation %templates:output(arg) to save a few more lines of code in template functions. Updated the docs (should actually be moved into documentation package).
Modified Paths:
--------------
apps/demo/examples/web/shakespeare.html
apps/demo/examples/web/shakespeare.xql
apps/demo/modules/config.xqm
apps/demo/modules/demo.xql
apps/demo/modules/templates.xql
apps/demo/templates/page.html
apps/demo/templates.html
Added Paths:
-----------
apps/demo/resources/images/eXide-screenshot.png
Modified: apps/demo/examples/web/shakespeare.html
===================================================================
--- apps/demo/examples/web/shakespeare.html 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/examples/web/shakespeare.html 2012-05-29 21:12:51 UTC (rev 16502)
@@ -24,7 +24,7 @@
<button type="submit">Query</button>
</div>
</form>
- <div class="shakespeare:query">
+ <div id="results" class="shakespeare:query">
<p>Found: <span id="hit-count" class="shakespeare:hit-count"/> matches.</p>
<div class="shakespeare:show-hits?howmany=20"/>
</div>
Modified: apps/demo/examples/web/shakespeare.xql
===================================================================
--- apps/demo/examples/web/shakespeare.xql 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/examples/web/shakespeare.xql 2012-05-29 21:12:51 UTC (rev 16502)
@@ -8,16 +8,20 @@
declare variable $shakes:SESSION := "shakespeare:results";
(:~
- Execute the query. The search results are not output immediately. Instead they
- are passed to nested templates through the $model parameter.
-:)
-declare function shakes:query($node as node()*, $model as item()*, $query as xs:string?, $mode as xs:string) {
+ : Execute a query and pass the result to nested template functions. The annotation
+ : %templates:output("model") indicates that we want the output of the function
+ : to become the new model for any nested template functions. The templating
+ : module copies the current element and its attributes, then continues processing
+ : its children.
+ :)
+declare
+ %templates:output("model")
+function shakes:query($node as node()*, $model as item()*, $query as xs:string?, $mode as xs:string) {
session:create(),
let $hits := shakes:do-query($query, $mode)
let $store := session:set-attribute($shakes:SESSION, $hits)
return
- (: Process nested templates :)
- <div id="results">{ templates:process($node/*, $hits) }</div>
+ $hits
};
declare function shakes:do-query($queryStr as xs:string?, $mode as xs:string) {
@@ -31,21 +35,26 @@
Read the last query result from the HTTP session and pass it to nested templates
in the $model parameter.
:)
-declare function shakes:from-session($node as node()*, $model as item()*) {
- let $hits := session:get-attribute($shakes:SESSION)
- return
- templates:process($node/*, $hits)
+declare
+ %templates:output("model")
+function shakes:from-session($node as node()*, $model as item()*) {
+ session:get-attribute($shakes:SESSION)
};
(:~
- Create a span with the number of items in the current search result.
-:)
-declare function shakes:hit-count($node as node()*, $model as item()*) {
- <span id="hit-count">{ count($model) }</span>
+ : Create a span with the number of items in the current search result.
+ : The annotation %templates:output("wrap") tells the templating module
+ : to create a new element with the same name and attributes as $node,
+ : using the return value of the function as its content.
+ :)
+declare
+ %templates:output("wrap")
+function shakes:hit-count($node as node()*, $model as item()*) {
+ count($model)
};
(:~
- Output the actual search result as a div, using the kwic module to summarize full text matches.
+ : Output the actual search result as a div, using the kwic module to summarize full text matches.
:)
declare
%templates:default("start", 1)
Modified: apps/demo/modules/config.xqm
===================================================================
--- apps/demo/modules/config.xqm 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/modules/config.xqm 2012-05-29 21:12:51 UTC (rev 16502)
@@ -25,6 +25,13 @@
substring-before($modulePath, "/modules")
;
+declare function config:resolve($relPath as xs:string) {
+ if (starts-with($config:app-root, "/db")) then
+ doc(concat($config:app-root, "/", $relPath))
+ else
+ doc(concat("file://", $config:app-root, "/", $relPath))
+};
+
(:~
: Returns the repo.xml descriptor for the current application.
:)
@@ -43,7 +50,7 @@
: For debugging: generates a table showing all properties defined
: in the application descriptors.
:)
-declare function config:app-info($node as node(), $model as item()*) {
+declare function config:app-info($node as node(), $params as element(parameters)?, $model as item()*) {
let $expath := config:expath-descriptor()
let $repo := config:repo-descriptor()
return
Modified: apps/demo/modules/demo.xql
===================================================================
--- apps/demo/modules/demo.xql 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/modules/demo.xql 2012-05-29 21:12:51 UTC (rev 16502)
@@ -29,7 +29,7 @@
: </ol>
:)
declare function demo:multiply($node as node()*, $model as item()*, $n1 as xs:int, $n2 as xs:int) {
- $p1 * $p2
+ $n1 * $n2
};
declare function demo:error-handler-test($node as node(), $model as item()*, $number as xs:string?) {
Modified: apps/demo/modules/templates.xql
===================================================================
--- apps/demo/modules/templates.xql 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/modules/templates.xql 2012-05-29 21:12:51 UTC (rev 16502)
@@ -4,6 +4,9 @@
(:~
: HTML templating module
+ :
+ : @version 2.0
+ : @author Wolfgang Meier
:)
import module namespace config="http://exist-db.org/xquery/apps/config" at "config.xqm";
@@ -91,7 +94,11 @@
let $inspect := util:inspect-function($fn)
let $args := templates:map-arguments($inspect, $parameters)
return
- templates:call-with-args($fn, $args, $node, $model)
+ templates:process-output(
+ $node,
+ templates:call-with-args($fn, $args, $node, $model),
+ $inspect
+ )
};
declare %private function templates:call-with-args($fn as function(*), $args as (function() as item()*)*,
@@ -115,6 +122,26 @@
error($templates:TOO_MANY_ARGS, "Too many arguments to function " || function-name($fn))
};
+declare %private function templates:process-output($node as element(), $output as item()*, $inspect as element(function)) {
+ let $anno :=
+ $inspect/annotation[ends-with(@name, ":output")]
+ [@namespace = "http://exist-db.org/xquery/templates"]
+ return
+ switch ($anno/value)
+ case "model" return
+ element { node-name($node) } {
+ $node/@*,
+ templates:process($node/node(), $output)
+ }
+ case "wrap" return
+ element { node-name($node) } {
+ $node/@*,
+ $output
+ }
+ default return
+ $output
+};
+
declare %private function templates:map-arguments($inspect as element(function), $parameters as element(parameters)) {
let $args := $inspect/argument
return
@@ -150,13 +177,14 @@
}
};
-declare function templates:arg-from-annotation($var as xs:string, $arg as element(argument)) {
+declare %private function templates:arg-from-annotation($var as xs:string, $arg as element(argument)) {
let $anno :=
$arg/../annotation[ends-with(@name, ":default")]
[@namespace = "http://exist-db.org/xquery/templates"]
[value[1] = $var]
+ for $value in subsequence($anno/value, 2)
return
- string($anno/value[2])
+ string($value)
};
declare %private function templates:resolve($arity as xs:int, $func as xs:string,
@@ -224,18 +252,16 @@
:-----------------------------------------------------------------------------------:)
declare function templates:include($node as node(), $model as item()*, $path as xs:string) {
- let $path := concat($config:app-root, "/", $path)
- return
- templates:process(doc($path), $model)
+ templates:process(config:resolve($path), $model)
};
declare function templates:surround($node as node(), $model as item()*, $with as xs:string, $at as xs:string?, $using as xs:string?) {
let $path := concat($config:app-root, "/", $with)
let $content :=
if ($using) then
- doc($path)//*[@id = $using]
+ config:resolve($with)//*[@id = $using]
else
- doc($path)
+ config:resolve($with)
let $merged := templates:process-surround($content, $node, $at)
return
templates:process($merged, $model)
Added: apps/demo/resources/images/eXide-screenshot.png
===================================================================
(Binary files differ)
Property changes on: apps/demo/resources/images/eXide-screenshot.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: apps/demo/templates/page.html
===================================================================
--- apps/demo/templates/page.html 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/templates/page.html 2012-05-29 21:12:51 UTC (rev 16502)
@@ -124,6 +124,9 @@
<li>
<a href="/cex-demo.html">Content Extraction</a>
</li>
+ <li>
+ <a href="/examples/tests/test.html">Unit Testing</a>
+ </li>
</ol>
</div>
</div>
Modified: apps/demo/templates.html
===================================================================
--- apps/demo/templates.html 2012-05-29 20:42:54 UTC (rev 16501)
+++ apps/demo/templates.html 2012-05-29 21:12:51 UTC (rev 16502)
@@ -3,10 +3,12 @@
<h1>Templating</h1>
<section>
<h2>Introduction</h2>
- <p>The Demo application uses templating. All pages are plain HTML5. They do not include any XQuery or other executable code.
- Instead, we use the <a class="templates:load-source" href="controller.xql">controller.xql</a> to send the HTML content through
- a templating library, which expands the HTML and calls our XQuery functions. The templating module scans the HTML for elements
- with class attributes with a certain structure and tries to translate them into XQuery function calls. In the simplest case,
+ <p>The templating module is used throughout this and most of the other applications which ship with
+ eXist. Its design has one goal: a clean separation of concerns. All views are plain, valid HTML5. They do
+ not include any XQuery or other executable code. Application code should go into separate XQuery modules
+ and will be called automagically by the templating framework.</p>
+ <p>The templating module scans the HTML for elements with class attributes following a simple convention
+ and tries to translate them into XQuery function calls. In the simplest case,
a class attribute which triggers a function call just contains the name of a function in an XQuery library
known to the system. For example:</p>
<pre class="brush: xml"><div class="demo:hello"></div></pre>
@@ -17,6 +19,9 @@
<pre class="brush: xml"><div class="demo:multiply?n1=5&n2=8"></div></pre>
<p>Again, the expanded output is shown below:</p>
<div class="demo:multiply?n1=5&n2=8"/>
+ <p>
+ <b>Note</b>: the <a href="modules/templates.xql" class="templates:load-source">templating module</a> is
+ itself entirely written in XQuery, making heavy use of XQuery 3.0 features like higher-order functions.</p>
</section>
<section>
<h2>Pre-defined Template Commands</h2>
@@ -42,38 +47,133 @@
<p>The surround template instruction is used by all pages of this demo application. The header, basic page structure and
menus are the same for all pages. Each page thus only contains a simple div with a template instruction:</p>
<pre class="brush: plain">templates:surround?with=templates/page.html&at=content</pre>
- <p>The instruction takes the content of the <a class="templates:load-source" href="templates.html">current element</a>
+ <p>The instruction takes the content of the current element
and injects it into the <a class="templates:load-source" href="templates/page.html">template page</a>.</p>
- <p>The XQuery function needs to have a special function signature. It should accept exactly three parameters:</p>
- <pre class="brush: xquery">demo:hello($node as node()*, $params as element(parameters)?, $model as item()*)</pre>
+ <h3>templates:form-control</h3>
+ <pre class="brush: plain">templates:form-control</pre>
+ <p>Use on <input> and <select> elements: checks the HTTP request for a parameter matching the
+ name of the form control and fills it into the value of an input or selects the corresponding option
+ of a select.</p>
+ <h3>templates:display-source</h3>
+ <pre class="brush: plain">templates:display-source?lang=language</pre>
+ <p>Display the contents of the element as a code block with syntax highlighting. This also adds a button
+ which copies the code into eXide if clicked.</p>
+ <h3>templates:load-source</h3>
+ <pre class="brush: plain">templates:load-source</pre>
+ <p>Normally used with an <a> element: opens the document referenced in the href attribute in eXide.</p>
</section>
<section>
<h2>Writing Template Functions</h2>
- <p>An XQuery function which should be called via the templating system needs to have a special function signature. It
- should accept exactly three parameters:</p>
- <pre class="brush: xquery">demo:hello($node as node(), $params as element(parameters)?, $model as item()*)</pre>
+ <p>The templating system is based on conventions: an XQuery function which should be called via the templating system
+ needs to accept at least two default parameters:</p>
+ <pre class="brush: xquery">demo:hello($node as node(), $model as item()*)</pre>
<dl>
<dt>$node</dt>
- <dd>The node which contained the template call.</dd>
- <dt>$params</dt>
- <dd>
- <p>An XML fragment describing all parameters passed through the template call. The fragment has the following
- structure:</p>
- <pre class="brush: xml">
- <parameters>
- <param name="name1" value="value1"/>
- </parameters></pre>
+ <dd>the node which contained the class attribute which triggered the templating call.</dd>
+ <dt>$model</dt>
+ <dd>is used to pass arbitrary information between template functions. See the section on "nesting templates"
+ below.
</dd>
- <dt>$model</dt>
- <dd>An arbitrary sequence which will be passed to nested template calls.</dd>
</dl>
+ <section>
+ <h3>
+ <a name="inject">Parameter Injection</a>
+ </h3>
+ <p>In addition to the default parameters, a templating function may take up to (currently) 8 additional parameters.
+ The templating system tries to determine a value for each of the additional parameters as follows:</p>
+ <ol>
+ <li>if the current HTTP request contains a (non-empty) parameter with the same name as the parameter variable,
+ it is used to set the value of the variable
+ </li>
+ <li>if the static parameters passed to the template call contain a parameter matching the variable name, it will
+ be used</li>
+ <li>if neither 1) nor 2) lead to a non-empty value, the function signature will be checked for an annotation
+ <code>%templates:default("name", "value1", ..., "valueN")</code>. The first parameter of the annotation should match
+ the name of the parameter variable. All other parameters of the annotation are taken as values for the
+ variable.</li>
+ </ol>
+ </section>
+ <section>
+ <h3>Type conversion</h3>
+ <p>When injecting parameters, the templating module tries to convert all values to the type specified for the
+ parameter in the function signature. For example, the function:</p>
+ <pre class="brush: xquery">declare function demo:multiply($node as node()*, $model as item()*, $n1 as xs:int, $n2 as xs:int)</pre>
+ <p>defines two optional parameters, $n1 and $n2 with type <code>xs:int</code>. Request and static parameters will
+ always be strings, so the templating module needs to transform them into the desired target type. This works for
+ all atomic types as well as XML elements and text nodes.</p>
+ </section>
+ </section>
+ <section>
+ <h2>Nesting Templates</h2>
<p>Template calls can be nested, but the outer template function needs to make sure all descendant XML nodes are passed
through the templating system. To do this, just call</p>
<pre class="brush: xquery">templates:process($children, $model)</pre>
<p>from within the template function. $children would contain the descendant nodes you want to include, $model may
contain arbitrary data you want to pass along to nested template calls.</p>
+ <p>The model is an important concept here: in a well designed application, all the information which is processed
+ by nested templates in a page should be contained in the model. For example, in the
+ <a href="examples/web/shakespeare.html">Shakespeare</a> example, there's an outer template call to
+ <code>shakespeare:query</code>, which runs a query on the data. The template does not return the query
+ result, but instead just puts it into the model. Displaying the results to the user is done by the two
+ nested templates: <code>shakespeare:hit-count</code> and <code>shakespeare:show-hits</code>.</p>
+ <p>
+ <code>shakespeare:query</code> could be implemented like this:</p>
+ <pre class="brush: xquery"><![CDATA[
+declare function shakes:query($node as node()*, $model as item()*, $query as xs:string?, $mode as xs:string) {
+ session:create(),
+ let $hits := shakes:do-query($query, $mode)
+ let $store := session:set-attribute($shakes:SESSION, $hits)
+ return
+ element { node-name($node) } {
+ $node/@*,
+ templates:process($node/*, $hits)
+ }
+};
+ ]]></pre>
+ <p>This function runs the query and creates a new element with the same name and attributes as the current element,
+ sets the model to the query result, and returns control to the templating framework to process any children
+ of the current element. This is a frequently used pattern and - as we'll see in the next section, there's a shortcut
+ for it which will save us most of the code in the return statement.</p>
</section>
<section>
+ <h2>Annotations</h2>
+ <p>The templating module defines an XQuery function annotation to handle a common case as the one above:
+ <code>%templates:output(param)</code>, where param may be either "model" or "wrap".</p>
+ <section>
+ <h3>%templates:output("wrap")</h3>
+ <p>By default, a templating function is expected to return an HTML fragment which replaces the current element.
+ If you need to preserve the current element as a wrapper around the function's output, you usually have to
+ manually create a new element with the same name and attributes as shown in the Shakespeare example
+ above. <code>%templates:output("wrap")</code> instructs the templating system to create this wrapper
+ element for you automatically.</p>
+ </section>
+ <section>
+ <h3>%templates:output("model")</h3>
+ <p>If this annotation is present, the templating module expects
+ the function to return a new model instead of HTML. Similar to "wrap", it constructs a new element with
+ the same name and attributes as the current one, but it also sets the model to the value returned by the
+ templating function and calls templates:process on any children.</p>
+ <p>The function "shakes:query" shown above can thus be simplified to:</p>
+ <pre class="brush: xquery"><![CDATA[
+declare
+ %templates:output("model")
+function shakes:query($node as node()*, $model as item()*, $query as xs:string?, $mode as xs:string) {
+ session:create(),
+ let $hits := shakes:do-query($query, $mode)
+ let $store := session:set-attribute($shakes:SESSION, $hits)
+ return
+ $hits
+};
+ ]]></pre>
+ </section>
+ <section>
+ <h3>%templates:default(name, value1, ..., valueN)</h3>
+ <p>As already discussed in the section on <a href="#inject">parameter injection</a>, this annotation is used to provide
+ static defaults for any optional parameter whose value cannot be determined by looking at the
+ HTTP request or static parameters.</p>
+ </section>
+ </section>
+ <section>
<h2>Call the Templating Module</h2>
<p>To trigger the templating, just call templates:apply from your main XQuery. templates:apply takes 3 parameters:</p>
<pre class="brush:xquery">templates:apply($content as node()+, $resolver as function(xs:string) as item()?, $model as item()*)</pre>
@@ -83,24 +183,28 @@
<dt>$resolver</dt>
<dd>A lookup function which will be called to find template functions.</dd>
<dt>$model</dt>
- <dd>The model: will be passed on to all called template functions.</dd>
+ <dd>The initial model: will be passed on to all called template functions.</dd>
</dl>
<p>The $resolver function has to be provided by the calling code because the templating module cannot access
- the context of the calling module. It takes one string argument: the name of the templating function
- to be called, and should return a function item if it could find the function, the empty sequence otherwise.
- Normally $resolver would just call function-lookup to resolve the function name to a function item and return it,
- but it is important that it catches any errors, e.g. caused by an invalid xs:QName.</p>
+ the context of the calling module and thus cannot see any of the function modules imported by the main
+ module. The function takes two arguments: the name of a function to look up and its arity, i.e.: the number of
+ arguments it takes. Normally $resolver will just call function-lookup to resolve the function name to a function
+ item and return it (if found), but it is important that it catches any errors, e.g. caused by an invalid xs:QName.</p>
<p>The main XQuery could thus look as simple as this:</p>
<pre class="brush:xquery">
+xquery version "3.0";
+
+import module namespace templates="http://exist-db.org/xquery/templates" at "templates.xql";
+
(: The following modules provide functions which will be called by the templating :)
-import module namespace i18n="http://exist-db.org/xquery/i18n/templates" at "i18n-templates.xql";
-import module namespace demo="http://exist-db.org/apps/demo" at "demo.xql";
+import module namespace shakespeare="http://exist-db.org/apps/demo/shakespeare" at "../examples/web/shakespeare.xql";
+import module namespace config="http://exist-db.org/xquery/apps/config" at "config.xqm";
declare option exist:serialize "method=html5 media-type=text/html";
-let $lookup := function($functionName as xs:string) {
+let $lookup := function($functionName as xs:string, $arity as xs:int) {
try {
- function-lookup(xs:QName($functionName), 3)
+ function-lookup(xs:QName($functionName), $arity)
} catch * {
()
}
@@ -109,8 +213,44 @@
return
templates:apply($content, $lookup, ())
</pre>
+ <p>This main XQuery will usually be called through the <code>controller.xql</code>. All that is needed is
+ one controller rule which redirects all requests for HTML pages to our main query:</p>
+ <pre class="brush: xquery"><![CDATA[
+else if (ends-with($exist:resource, ".html")) then
+ <dispatch xmlns="" rel="nofollow">http://exist.sourceforge.net/NS/exist">
+ <view>
+ <forward url="{$exist:controller}/modules/view.xql">
+ <set-attribute name="$exist:prefix" value="{$exist:prefix}"/>
+ <set-attribute name="$exist:controller" value="{$exist:controller}"/>
+ </forward>
+ </view>
+ <error-handler>
+ <forward url="{$exist:controller}/error-page.html" method="get"/>
+ <forward url="{$exist:controller}/modules/view.xql"/>
+ </error-handler>
+ </dispatch>
+ ]]></pre>
</section>
- <div class="source-links">
- <p>View source: <a href="templates.html" class="templates:load-source">this page</a>.</p>
- </div>
+ <section>
+ <h2>Integration with eXide</h2>
+ <p>eXide automatically integrates the templating framework into a new application if "HTML Templates" is
+ selected in the "Application Properties":</p>
+ <figure>
+ <img src="resources/images/eXide-screenshot.png"/>
+ </figure>
+ <p>eXide generates a corresponding main XQuery and a controller. The templating will work out of the
+ box for all HTML views.</p>
+ </section>
+ <section>
+ <h2>Source Links</h2>
+ <ul>
+ <li>The <a href="modules/view.xql" class="templates:load-source">main XQuery</a> which triggers the
+ templating in this app.</li>
+ <li>Shakespeare app: the <a href="examples/web/shakespeare.html" class="templates:load-source">HTML</a>
+ and the <a href="examples/web/shakespeare.xql" class="templates:load-source">XQuery module</a> implementing
+ the templating functions.</li>
+ <li>The source code of the <a href="modules/templates.xql" class="templates:load-source">templating module</a>
+ itself.</li>
+ </ul>
+ </section>
</article>
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <del...@us...> - 2012-05-29 20:43:02
|
Revision: 16501
http://exist.svn.sourceforge.net/exist/?rev=16501&view=rev
Author: deliriumsky
Date: 2012-05-29 20:42:54 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[refactor] further abstaction into EXQuery. Build is fixed. Persistence is temporarily disabled. More to come soon. Almost there!!!
Modified Paths:
--------------
branches/adam/project-sleepy/lib/core/exquery-annotations-common-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-annotations-common-api-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-common-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-restxq-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-restxq-api-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-serialization-annotations-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-serialization-annotations-api-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-xquery-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/lib/core/exquery-xquery3-1.0-SNAPSHOT.jar
branches/adam/project-sleepy/src/org/exist/http/sleepy/RESTfulXQueryService.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/CompiledHTTPRESTfulXQueryCache.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryService.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServiceRegistry.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServlet.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/RESTResponse.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/URIOrderedHttpMethodList.java
branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/XQueryCompilationTrigger.java
Modified: branches/adam/project-sleepy/lib/core/exquery-annotations-common-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-annotations-common-api-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-common-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-restxq-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-restxq-api-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-serialization-annotations-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-serialization-annotations-api-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-xquery-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/lib/core/exquery-xquery3-1.0-SNAPSHOT.jar
===================================================================
(Binary files differ)
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/RESTfulXQueryService.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/RESTfulXQueryService.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/RESTfulXQueryService.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -55,5 +55,5 @@
public boolean canService(final HttpRequest httpRequest);
//TODO how to remove DBBroker from here, inject in an interface for context?
- public void service(final DBBroker broker, final HttpRequest httpRequest, final HttpResponse httpResponse);
+ public void service(final DBBroker broker, final HttpRequest httpRequest, final HttpResponse httpResponse) throws RESTfulXQueryServiceException;
}
\ No newline at end of file
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/CompiledHTTPRESTfulXQueryCache.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/CompiledHTTPRESTfulXQueryCache.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/CompiledHTTPRESTfulXQueryCache.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -68,7 +68,7 @@
}
if(xquery == null) {
- xquery = XQueryCompiler.compile(broker, service.getXQueryLocation());
+ xquery = XQueryCompiler.compile(broker, service.getResourceFunction().getXQueryLocation());
}
//reset the state of the query
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryService.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryService.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryService.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -26,12 +26,9 @@
*/
package org.exist.http.sleepy.impl;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.*;
import javax.xml.transform.OutputKeys;
import org.apache.commons.io.input.CloseShieldInputStream;
import org.exist.dom.NodeSet;
@@ -39,11 +36,6 @@
import org.exist.http.BadRequestException;
import org.exist.http.sleepy.RESTfulXQueryService;
import org.exist.http.sleepy.RESTfulXQueryServiceException;
-import org.exist.http.sleepy.annotations.BinaryTypedParameter;
-import org.exist.http.sleepy.annotations.DefaultTypedParameter;
-import org.exquery.xquery.TypedParameter;
-import org.exquery.serialization.annotations.MethodAnnotation;
-import org.exist.http.sleepy.annotations.output.SerializationAnnotation;
import org.exist.http.sleepy.impl.adapters.TypeAdapter;
import org.exist.memtree.DocumentImpl;
import org.exist.memtree.ElementImpl;
@@ -53,6 +45,7 @@
import org.exist.storage.serializers.EXistOutputKeys;
import org.exist.storage.serializers.Serializer;
import org.exist.util.MimeType;
+import org.exist.util.serializer.AttrList;
import org.exist.util.serializer.SAXSerializer;
import org.exist.util.serializer.SerializerPool;
import org.exist.xquery.*;
@@ -61,11 +54,17 @@
import org.exquery.http.HttpMethod;
import org.exquery.http.HttpRequest;
import org.exquery.http.HttpResponse;
+import org.exquery.restxq.Namespace;
import org.exquery.restxq.ResourceFunction;
import org.exquery.restxq.annotation.HttpMethodAnnotation;
+import org.exquery.restxq.annotation.HttpMethodWithBodyAnnotation;
import org.exquery.restxq.annotation.ParameterAnnotation;
+import org.exquery.serialization.annotation.MethodAnnotation;
+import org.exquery.serialization.annotation.SerializationAnnotation;
import org.exquery.xquery.FunctionArgument;
import org.exquery.xquery.FunctionSignature;
+import org.exquery.xquery.TypedArgumentValue;
+import org.exquery.xquery.TypedValue;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
@@ -132,9 +131,9 @@
return resourceFunction;
}
- private EnumSet<HttpMethod> getServicedMethods() {
+ public EnumSet<HttpMethod> getServicedMethods() {
final EnumSet<HttpMethod> servicedMethods = EnumSet.noneOf(HttpMethod.class);
- for(HttpMethodAnnotation httpMethodAnnotation : getResourceFunction().getHttpMethodAnnotations()) {
+ for(final HttpMethodAnnotation httpMethodAnnotation : getResourceFunction().getHttpMethodAnnotations()) {
servicedMethods.add(httpMethodAnnotation.getHttpMethod());
}
return servicedMethods;
@@ -185,7 +184,7 @@
}
@Override
- public void service(final DBBroker broker, final HttpRequest request, HttpResponse response) {
+ public void service(final DBBroker broker, final HttpRequest request, HttpResponse response) throws RESTfulXQueryServiceException {
final CompiledHTTPRESTfulXQueryCache cache = CompiledHTTPRESTfulXQueryCache.getInstance();
CompiledXQuery xquery = null;
@@ -213,12 +212,10 @@
//serialize the results
serialize(result, response, broker);
- } catch(RESTfulXQueryServiceException se) {
- serializeExceptionResponse(response, se);
} catch(XPathException xpe) {
- serializeExceptionResponse(response, xpe);
+ throw new RESTfulXQueryServiceException(xpe.getMessage(), xpe);
} catch(BadRequestException bde) {
- serializeExceptionResponse(response, bde);
+ throw new RESTfulXQueryServiceException(bde.getMessage(), bde);
} finally {
//clear down monitoring
@@ -232,28 +229,39 @@
}
}
+ private Set<HttpMethodWithBodyAnnotation> getBodyContentAnnotations() {
+ final Set<HttpMethodWithBodyAnnotation> bodyContentAnnotations = new HashSet<HttpMethodWithBodyAnnotation>();
+ for(final HttpMethodAnnotation methodAnnotation : getResourceFunction().getHttpMethodAnnotations()) {
+ if(methodAnnotation instanceof HttpMethodWithBodyAnnotation) {
+ bodyContentAnnotations.add((HttpMethodWithBodyAnnotation)methodAnnotation);
+ }
+ }
+ return bodyContentAnnotations;
+ }
+
private FunctionCall createFunctionCall(final CompiledXQuery xquery, final UserDefinedFunction fn, final HttpRequest request) throws XPathException {
final FunctionCall fnCall = new FunctionCall(xquery.getContext(), fn);
+ final Map<String, Item> paramNameValues = new HashMap<String, Item>();
- final Map<String, String> paramNameValues = new HashMap<String, String>();
-
//extract the param mappings for the Path Annotation
- paramNameValues.putAll(getResourceFunction().getPathAnnotation().extractPathParameters(request.getPath()));
+ for(Entry<String, String> pathParameter : getResourceFunction().getPathAnnotation().extractPathParameters(request.getPath()).entrySet()) {
+ paramNameValues.put(pathParameter.getKey(), new StringValue(pathParameter.getValue()));
+ }
//extract the param mappings for the Body Content Annotations
if(!getBodyContentAnnotations().isEmpty()) {
final Item requestBody = parseRequestBody(xquery.getContext(), request);
- for(AbstractBodyContentAnnotation bodyContentAnnotation : getBodyContentAnnotations()) {
- paramNameValues.put(bodyContentAnnotation.getBodyFnParamName(), requestBody);
+ for(final HttpMethodWithBodyAnnotation bodyContentAnnotation : getBodyContentAnnotations()) {
+ paramNameValues.put(bodyContentAnnotation.getBodyParameterName(), requestBody);
}
}
//extract the param mappings for Param Annotations
- for(ParameterAnnotation parameterAnnotation : getResourceFunction().getParameterAnnotations()) {
- final Entry<String, TypedParameter> paramNameValue = parameterAnnotation.extractParameter(request);
- paramNameValues.put(paramNameValue.getKey(), typedParameterToItem(xquery.getContext(), paramNameValue.getValue()));
+ for(final ParameterAnnotation parameterAnnotation : getResourceFunction().getParameterAnnotations()) {
+ final TypedArgumentValue typedArgumentValue = parameterAnnotation.extractParameter(request);
+ paramNameValues.put(typedArgumentValue.getArgumentName(), typedValueToItem(xquery.getContext(), typedArgumentValue.getTypedValue()));
}
@@ -408,7 +416,7 @@
private void processSerializationAnnotations(final Properties outputProperties) {
//get the serialzation annotations
- for(SerializationAnnotation serializationAnnotation : getSerializationAnnotations()) {
+ for(SerializationAnnotation serializationAnnotation : getResourceFunction().getSerializationAnnotations()) {
if(serializationAnnotation instanceof MethodAnnotation) {
final String method = ((MethodAnnotation)serializationAnnotation).getMethod();
outputProperties.setProperty("method", method);
@@ -470,7 +478,7 @@
try {
sax = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
- Writer writer = new OutputStreamWriter(response.getOutputStream(), outputProperties.getProperty(OutputKeys.ENCODING));
+ final Writer writer = new OutputStreamWriter(response.getOutputStream(), outputProperties.getProperty(OutputKeys.ENCODING));
sax.setOutput(writer, outputProperties);
serializer.setProperties(outputProperties);
@@ -483,23 +491,84 @@
writer.close();
} catch(IOException ioe) {
- throw new BadRequestException("Error while serializing xml: " + ioe.toString(), ioe);
+ throw new BadRequestException("Error while serializing XML: " + ioe.toString(), ioe);
} catch(SAXException se) {
- throw new BadRequestException("Error while serializing xml: " + se.toString(), se);
+ throw new BadRequestException("Error while serializing XML: " + se.toString(), se);
} finally {
if(sax != null) {
SerializerPool.getInstance().returnObject(sax);
}
}
}
+
+ public void serializeExceptionResponse(final HttpResponse response, final Exception e, final DBBroker broker) throws BadRequestException {
+ //serialize the exception
+ final Serializer serializer = broker.getSerializer();
+ serializer.reset();
+ SAXSerializer sax = null;
+ try {
+ sax = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
+
+ final Properties outputProperties = new Properties();
+ outputProperties.putAll(DEFAULT_SERIALIZATION_PROPERTIES);
+
+ final Writer writer = new OutputStreamWriter(response.getOutputStream(), outputProperties.getProperty(OutputKeys.ENCODING));
+ sax.setOutput(writer, outputProperties);
+
+ serializer.setProperties(outputProperties);
+ serializer.setSAXHandlers(sax, sax);
+
+ final QName qnResponse = new QName("response", Namespace.ANNOTATION_NS);
+ final QName qnException = new QName("exception", Namespace.ANNOTATION_ERROR_NS);
+ final QName message = new QName("message", Namespace.ANNOTATION_ERROR_NS);
+ final QName qnStack = new QName("stack", Namespace.ANNOTATION_ERROR_NS);
- private Item typedParameterToItem(final XQueryContext context, final TypedParameter typedParameter) throws XPathException {
- if(typedParameter instanceof DefaultTypedParameter) {
- return new StringValue(((DefaultTypedParameter)typedParameter).getValue());
- } else if(typedParameter instanceof BinaryTypedParameter) {
- return BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), ((BinaryTypedParameter)typedParameter).getValue());
+ sax.startDocument();
+ sax.startElement(qnResponse, null);
+ sax.startElement(qnException, null);
+ sax.startElement(message, null);
+ sax.characters(e.getClass().getName() + ": " + e.getLocalizedMessage());
+
+ final StackTraceElement[] trace = e.getStackTrace();
+ for(final StackTraceElement element : trace) {
+
+ final AttrList attrs = new AttrList(){{
+ addAttribute(new QName("file"), element.getFileName());
+ addAttribute(new QName("class"), element.getClassName());
+ addAttribute(new QName("method"), element.getMethodName());
+ addAttribute(new QName("line"), Integer.toString(element.getLineNumber()));
+ }};
+
+ sax.startElement(qnStack, attrs);
+ sax.endElement(qnStack);
+ }
+
+ sax.endElement(message);
+ sax.endElement(qnException);
+ sax.endElement(qnResponse);
+ sax.endDocument();
+
+ writer.flush();
+ writer.close();
+
+ } catch(IOException ioe) {
+ throw new BadRequestException("Error while serializing XML for exception '" + e.getClass().getName() + ":" + e.getMessage() + "': " + ioe.toString(), ioe);
+ } catch(SAXException se) {
+ throw new BadRequestException("Error while serializing XML for exception '" + e.getClass().getName() + ":" + e.getMessage() + "': " + se.toString(), se);
+ } finally {
+ if(sax != null) {
+ SerializerPool.getInstance().returnObject(sax);
+ }
+ }
+ }
+
+ private Item typedValueToItem(final XQueryContext context, final TypedValue typedValue) throws XPathException {
+ if(typedValue.getType().equals(org.exquery.xquery.Type.STRING)) {
+ return new StringValue((String)typedValue.getValue());
+ } else if(typedValue.getType().equals(org.exquery.xquery.Type.BASE64_BINARY)) {
+ return BinaryValueFromInputStream.getInstance(context, new Base64BinaryValueType(), (InputStream)typedValue.getValue());
} else {
- throw new XPathException("Could not convert TypedParameter: " + typedParameter.getClass().getName() + " to org.exist.xquery.value.Item");
+ throw new XPathException("Could not convert TypedValue of type: " + typedValue.getType().name() + " for class " + typedValue.getValue().getClass().getName() + " to org.exist.xquery.value.Item");
}
}
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServiceRegistry.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServiceRegistry.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServiceRegistry.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -26,20 +26,15 @@
*/
package org.exist.http.sleepy.impl;
-import java.io.*;
-import java.lang.reflect.Constructor;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
import java.net.URI;
-import java.util.*;
-import org.apache.commons.io.FileUtils;
+import java.util.EnumSet;
+import java.util.List;
import org.exist.http.sleepy.RESTfulXQueryService;
import org.exist.http.sleepy.RESTfulXQueryServiceRegistry;
-import org.exist.http.sleepy.annotations.AnnotationWrapper;
-import org.exist.http.sleepy.annotations.output.SerializationAnnotation;
-import org.exist.http.sleepy.annotations.rest.AbstractBodyContentAnnotation;
-import org.exquery.restxq.impl.annotation.AbstractParameterAnnotation;
-import org.exist.http.sleepy.annotations.rest.PathAnnotation;
-import org.exist.http.sleepy.impl.URIOrderedHttpMethodList.ListTask;
-import org.exist.http.sleepy.impl.adapters.AnnotationAdapter;
import org.exquery.http.HttpMethod;
import org.exquery.http.HttpRequest;
@@ -97,93 +92,93 @@
}
public void loadState(final File dataDir) throws IOException {
- getServices().executeExclusiveWrite(new ListTask<HttpMethod, HTTPRESTfulXQueryService>(){
- @Override
- public void execute(Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) throws IOException {
-
- //clear the registry
- empty(uriOrderedMethodList);
-
- final File fRegistry = new File(dataDir, REGISTRY_FILENAME);
- DataInputStream is = null;
- try {
- is = new DataInputStream(new BufferedInputStream(new FileInputStream(fRegistry)));
- final byte
- if(onDiskVersion != ON_DISK_VERSION) {
- throw new IOException("Expected Registry file version: " + ON_DISK_VERSION + " but got version: " + onDiskVersion);
- }
-
- final int serviceCount = is.readInt();
- for(int i = 0; i < serviceCount; i++) {
- final HTTPRESTfulXQueryService service = new HTTPRESTfulXQueryService();
- loadServiceState(is, service);
- register(service);
- }
-
- } finally {
- if(is != null) {
- is.close();
- }
- }
- }
-
- private void empty(final Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) {
-
- final Set<RESTfulXQueryService> uniqueServices = new HashSet<RESTfulXQueryService>();
- for(List<HTTPRESTfulXQueryService> services : uriOrderedMethodList.values()) {
- for(RESTfulXQueryService Service: services) {
- uniqueServices.add(Service);
- }
- }
-
- //remove the compiled representations form the Cache
- CompiledHTTPRESTfulXQueryCache.getInstance().removeServices(uniqueServices);
-
- //empty the list
- uriOrderedMethodList.clear();
- }
- });
+// getServices().executeExclusiveWrite(new ListTask<HttpMethod, HTTPRESTfulXQueryService>(){
+// @Override
+// public void execute(Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) throws IOException {
+//
+// //clear the registry
+// empty(uriOrderedMethodList);
+//
+// final File fRegistry = new File(dataDir, REGISTRY_FILENAME);
+// DataInputStream is = null;
+// try {
+// is = new DataInputStream(new BufferedInputStream(new FileInputStream(fRegistry)));
+// final byte
+// if(onDiskVersion != ON_DISK_VERSION) {
+// throw new IOException("Expected Registry file version: " + ON_DISK_VERSION + " but got version: " + onDiskVersion);
+// }
+//
+// final int serviceCount = is.readInt();
+// for(int i = 0; i < serviceCount; i++) {
+// final HTTPRESTfulXQueryService service = new HTTPRESTfulXQueryService();
+// loadServiceState(is, service);
+// register(service);
+// }
+//
+// } finally {
+// if(is != null) {
+// is.close();
+// }
+// }
+// }
+//
+// private void empty(final Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) {
+//
+// final Set<RESTfulXQueryService> uniqueServices = new HashSet<RESTfulXQueryService>();
+// for(List<HTTPRESTfulXQueryService> services : uriOrderedMethodList.values()) {
+// for(RESTfulXQueryService Service: services) {
+// uniqueServices.add(Service);
+// }
+// }
+//
+// //remove the compiled representations form the Cache
+// CompiledHTTPRESTfulXQueryCache.getInstance().removeServices(uniqueServices);
+//
+// //empty the list
+// uriOrderedMethodList.clear();
+// }
+// });
}
public void saveState(final File dataDir) throws IOException {
- getServices().executeExclusiveRead(new ListTask<HttpMethod, HTTPRESTfulXQueryService>(){
- @Override
- public void execute(final Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) throws IOException {
-
- final File fNewRegistry = new File(dataDir, REGISTRY_FILENAME_TMP);
- DataOutputStream os = null;
- try {
- os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fNewRegistry)));
- os.write(ON_DISK_VERSION);
-
- final Set<HTTPRESTfulXQueryService> distinctServices = new HashSet<HTTPRESTfulXQueryService>();
-
- //serialize each service
- for(final List<HTTPRESTfulXQueryService> servicesList : uriOrderedMethodList.values()) {
- for(final HTTPRESTfulXQueryService service : servicesList) {
- if(!distinctServices.contains(service)) {
- distinctServices.add(service);
- }
- }
- }
-
- os.writeInt(distinctServices.size());
- for(HTTPRESTfulXQueryService service : distinctServices) {
- saveServiceState(os, service);
- }
- } finally {
- if(os != null) {
- os.close();
- }
- }
-
- //replace the old file with the new file
- final File fRegistry = new File(dataDir, REGISTRY_FILENAME);
- FileUtils.deleteQuietly(fRegistry);
- FileUtils.moveFile(fNewRegistry, fRegistry);
- }
- });
+// getServices().executeExclusiveRead(new ListTask<HttpMethod, HTTPRESTfulXQueryService>(){
+// @Override
+// public void execute(final Map<HttpMethod, List<HTTPRESTfulXQueryService>> uriOrderedMethodList) throws IOException {
+//
+// final File fNewRegistry = new File(dataDir, REGISTRY_FILENAME_TMP);
+// DataOutputStream os = null;
+// try {
+// os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(fNewRegistry)));
+// os.write(ON_DISK_VERSION);
+//
+// final Set<HTTPRESTfulXQueryService> distinctServices = new HashSet<HTTPRESTfulXQueryService>();
+//
+// //serialize each service
+// for(final List<HTTPRESTfulXQueryService> servicesList : uriOrderedMethodList.values()) {
+// for(final HTTPRESTfulXQueryService service : servicesList) {
+// if(!distinctServices.contains(service)) {
+// distinctServices.add(service);
+// }
+// }
+// }
+//
+// os.writeInt(distinctServices.size());
+// for(HTTPRESTfulXQueryService service : distinctServices) {
+// saveServiceState(os, service);
+// }
+// } finally {
+// if(os != null) {
+// os.close();
+// }
+// }
+//
+// //replace the old file with the new file
+// final File fRegistry = new File(dataDir, REGISTRY_FILENAME);
+// FileUtils.deleteQuietly(fRegistry);
+// FileUtils.moveFile(fNewRegistry, fRegistry);
+// }
+// });
}
/**
@@ -203,77 +198,79 @@
*/
private void saveServiceState(final DataOutputStream os, final HTTPRESTfulXQueryService service) throws IOException {
- os.writeUTF(service.getXQueryLocation().toString());
-
- os.writeInt(service.getServicedMethods().size());
- for(final HttpMethod servicedMethod : service.getServicedMethods()) {
- os.writeInt(servicedMethod.ordinal());
- }
-
- final List<AnnotationWrapper> allAnnotations = new ArrayList<AnnotationWrapper>();
- allAnnotations.add(service.getPathAnnotation());
- allAnnotations.addAll(service.getSerializationAnnotations());
- allAnnotations.addAll(service.getBodyContentAnnotations());
- allAnnotations.addAll(service.getParamAnnotations());
- allAnnotations.addAll(service.getOtherAnnotations());
-
- os.writeInt(allAnnotations.size());
-
- for(final AnnotationWrapper an : allAnnotations) {
- an.serialize(os);
- }
+// os.writeUTF(service.getXQueryLocation().toString());
+//
+// os.writeInt(service.getServicedMethods().size());
+// for(final HttpMethod servicedMethod : service.getServicedMethods()) {
+// os.writeInt(servicedMethod.ordinal());
+// }
+//
+// final List<AnnotationWrapper> allAnnotations = new ArrayList<AnnotationWrapper>();
+// allAnnotations.add(service.getPathAnnotation());
+// allAnnotations.addAll(service.getSerializationAnnotations());
+// allAnnotations.addAll(service.getBodyContentAnnotations());
+// allAnnotations.addAll(service.getParamAnnotations());
+// allAnnotations.addAll(service.getOtherAnnotations());
+//
+// os.writeInt(allAnnotations.size());
+//
+// for(final AnnotationWrapper an : allAnnotations) {
+// an.serialize(os);
+// }
}
public void loadServiceState(final DataInputStream is, final HTTPRESTfulXQueryService service) throws IOException {
- service.setXQueryLocation(URI.create(is.readUTF()));
- final int servicedMethodsSize = is.readInt();
- service.getServicedMethods().clear();
- for(int i = 0; i < servicedMethodsSize; i++) {
- final int servicedMethodOrdinal = is.readInt();
- service.getServicedMethods().add(HttpMethod.values()[servicedMethodOrdinal]);
- }
- /* following is AnnotationWrappers */
- //1) clear any annotations
- service.setPathAnnotation(null);
- service.getSerializationAnnotations().clear();
- service.getBodyContentAnnotations().clear();
- service.getParamAnnotations().clear();
- service.getOtherAnnotations().clear();
-
- //2) load annotations
- try {
- final int annotationWrappers = is.readInt();
- for(int i = 0; i < annotationWrappers; i++) {
- final String className = is.readUTF();
-
- final Class clazz = Class.forName(className);
- final Constructor cstrAnnotationWrapper = clazz.getConstructor(org.exquery.xquery3.Annotation.class);
-
- final AnnotationAdapter annotation = new AnnotationAdapter();
- annotation.deserialize(is);
-
- final AnnotationWrapper aw = (AnnotationWrapper)cstrAnnotationWrapper.newInstance(annotation);
- aw.initialise();
-
- if(aw instanceof PathAnnotation) {
- service.setPathAnnotation((PathAnnotation)aw);
- } else if(aw instanceof SerializationAnnotation) {
- service.getSerializationAnnotations().add((SerializationAnnotation)aw);
- } else if(aw instanceof AbstractBodyContentAnnotation) {
- service.getBodyContentAnnotations().add((AbstractBodyContentAnnotation)aw);
- } else if(aw instanceof AbstractParameterAnnotation) {
- service.getParamAnnotations().add((AbstractParameterAnnotation)aw);
- } else {
- service.getOtherAnnotations().add(aw);
- }
- }
- } catch(Exception e) {
- throw new IOException(e.getMessage(), e);
- //TODO perhaps should throw different exception, like RESTFulXQueryService exception - propbably best to externalise serialization
- }
+// service.setXQueryLocation(URI.create(is.readUTF()));
+//
+// final int servicedMethodsSize = is.readInt();
+// service.getServicedMethods().clear();
+// for(int i = 0; i < servicedMethodsSize; i++) {
+// final int servicedMethodOrdinal = is.readInt();
+// service.getServicedMethods().add(HttpMethod.values()[servicedMethodOrdinal]);
+// }
+//
+// /* following is AnnotationWrappers */
+// //1) clear any annotations
+// service.setPathAnnotation(null);
+// service.getSerializationAnnotations().clear();
+// service.getBodyContentAnnotations().clear();
+// service.getParamAnnotations().clear();
+// service.getOtherAnnotations().clear();
+//
+// //2) load annotations
+// try {
+// final int annotationWrappers = is.readInt();
+// for(int i = 0; i < annotationWrappers; i++) {
+// final String className = is.readUTF();
+//
+// final Class clazz = Class.forName(className);
+// final Constructor cstrAnnotationWrapper = clazz.getConstructor(org.exquery.xquery3.Annotation.class);
+//
+// final AnnotationAdapter annotation = new AnnotationAdapter();
+// annotation.deserialize(is);
+//
+// final AnnotationWrapper aw = (AnnotationWrapper)cstrAnnotationWrapper.newInstance(annotation);
+// aw.initialise();
+//
+// if(aw instanceof PathAnnotation) {
+// service.setPathAnnotation((PathAnnotation)aw);
+// } else if(aw instanceof SerializationAnnotation) {
+// service.getSerializationAnnotations().add((SerializationAnnotation)aw);
+// } else if(aw instanceof AbstractBodyContentAnnotation) {
+// service.getBodyContentAnnotations().add((AbstractBodyContentAnnotation)aw);
+// } else if(aw instanceof AbstractParameterAnnotation) {
+// service.getParamAnnotations().add((AbstractParameterAnnotation)aw);
+// } else {
+// service.getOtherAnnotations().add(aw);
+// }
+// }
+// } catch(Exception e) {
+// throw new IOException(e.getMessage(), e);
+// //TODO perhaps should throw different exception, like RESTFulXQueryService exception - propbably best to externalise serialization
+// }
}
private URIOrderedHttpMethodList<HttpMethod, HTTPRESTfulXQueryService> getServices() {
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServlet.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServlet.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/HTTPRESTfulXQueryServlet.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -36,6 +36,7 @@
import org.exist.EXistException;
import org.exist.http.servlets.AbstractExistHttpServlet;
import org.exist.http.sleepy.RESTfulXQueryService;
+import org.exist.http.sleepy.RESTfulXQueryServiceException;
import org.exist.http.sleepy.impl.adapters.HttpServletRequestAdapter;
import org.exist.http.sleepy.impl.adapters.HttpServletResponseAdapter;
import org.exist.security.Subject;
@@ -44,7 +45,6 @@
import org.exist.util.Configuration;
import org.exist.util.io.FilterInputStreamCacheFactory.FilterInputStreamCacheConfiguration;
import org.exquery.http.HttpMethod;
-import org.exquery.http.HttpMethod;
import org.exquery.http.HttpRequest;
/**
@@ -133,6 +133,9 @@
} catch(EXistException ee) {
getLog().error(ee.getMessage(), ee);
throw new ServletException(ee.getMessage(), ee);
+ } catch(RESTfulXQueryServiceException rqse) {
+ getLog().error(rqse.getMessage(), rqse);
+ throw new ServletException(rqse.getMessage(), rqse);
} finally {
if(broker != null) {
getPool().release(broker);
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/RESTResponse.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/RESTResponse.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/RESTResponse.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -28,9 +28,9 @@
import java.util.Properties;
import org.exist.dom.QName;
-import org.exquery.restxq.Namespace;
import static org.expath.httpclient.HttpConstants.HTTP_CLIENT_NS_URI;
import org.exquery.http.HttpResponse;
+import org.exquery.restxq.Namespace;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/URIOrderedHttpMethodList.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/URIOrderedHttpMethodList.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/URIOrderedHttpMethodList.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -86,7 +86,7 @@
final List<V> serviceList = uriOrderedMethodList.get(key);
for(V service : serviceList) {
- if(service.getXQueryLocation().equals(uri)) {
+ if(service.getResourceFunction().getXQueryLocation().equals(uri)) {
//remove the compiled representations form the Cache
CompiledHTTPRESTfulXQueryCache.getInstance().removeService(service);
Modified: branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/XQueryCompilationTrigger.java
===================================================================
--- branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/XQueryCompilationTrigger.java 2012-05-29 17:07:57 UTC (rev 16500)
+++ branches/adam/project-sleepy/src/org/exist/http/sleepy/impl/XQueryCompilationTrigger.java 2012-05-29 20:42:54 UTC (rev 16501)
@@ -28,9 +28,7 @@
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
import org.exist.collections.triggers.FilteringTrigger;
import org.exist.collections.triggers.TriggerException;
import org.exist.dom.DocumentImpl;
@@ -42,8 +40,10 @@
import org.exist.xquery.Annotation;
import org.exist.xquery.CompiledXQuery;
import org.exist.xquery.UserDefinedFunction;
-import org.exquery.annotation.AnnotationException;
+import org.exquery.ExQueryException;
import org.exquery.restxq.ResourceFunction;
+import org.exquery.restxq.impl.ResourceFunctionFactory;
+import org.exquery.restxq.impl.annotation.RestAnnotationFactory;
/**
*
@@ -156,27 +156,21 @@
final UserDefinedFunction function = itFunctions.next();
final Annotation annotations[] = function.getSignature().getAnnotations();
-
-
-
-
-
-
- List<AnnotationWrapper> functionRestAnnotations = null;
+ Set<org.exquery.xquery3.Annotation> functionRestAnnotations = null;
//process the function annotations
for(final Annotation annotation : annotations) {
if(RestAnnotationFactory.isRestXqAnnotation(annotation.getName().toJavaQName())) {
- final AnnotationWrapper restAnnotation = RestAnnotationFactory.getAnnotation(new AnnotationAdapter(annotation));
+ final org.exquery.xquery3.Annotation restAnnotation = RestAnnotationFactory.getAnnotation(new AnnotationAdapter(annotation));
if(functionRestAnnotations == null) {
- functionRestAnnotations = new ArrayList<AnnotationWrapper>();
+ functionRestAnnotations = new HashSet<org.exquery.xquery3.Annotation>();
}
functionRestAnnotations.add(restAnnotation);
}
}
if(functionRestAnnotations != null) {
- final ResourceFunction resourceFunction = ResourceFunctionFactory.create(document.getURI(), functionRestAnnotations);
+ final ResourceFunction resourceFunction = ResourceFunctionFactory.create(document.getURI().getURI(), functionRestAnnotations);
final HTTPRESTfulXQueryService service = new HTTPRESTfulXQueryService(resourceFunction);
//add service and compiled query to the cache
@@ -188,8 +182,8 @@
}
} catch(RESTfulXQueryServiceCompilationException ce) {
throw new TriggerException(ce.getMessage(), ce);
- } catch(AnnotationException rae) {
- throw new TriggerException(rae.getMessage(), rae);
+ } catch(ExQueryException exqe) {
+ throw new TriggerException(exqe.getMessage(), exqe);
}
return services;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-29 17:08:08
|
Revision: 16500
http://exist.svn.sourceforge.net/exist/?rev=16500&view=rev
Author: shabanovd
Date: 2012-05-29 17:07:57 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[ignore] try to find NPE place
Modified Paths:
--------------
trunk/eXist/src/org/exist/xquery/Profiler.java
Modified: trunk/eXist/src/org/exist/xquery/Profiler.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/Profiler.java 2012-05-29 16:13:45 UTC (rev 16499)
+++ trunk/eXist/src/org/exist/xquery/Profiler.java 2012-05-29 17:07:57 UTC (rev 16500)
@@ -25,6 +25,7 @@
import org.apache.log4j.Logger;
import org.exist.Database;
+import org.exist.storage.DBBroker;
import org.exist.xquery.value.Sequence;
/**
@@ -138,7 +139,8 @@
}
public final boolean isLogEnabled() {
- Boolean globalProp = (Boolean) db.getActiveBroker().getConfiguration().getProperty(CONFIG_PROPERTY_TRACELOG);
+ DBBroker broker = db.getActiveBroker();
+ Boolean globalProp = (Boolean) broker.getConfiguration().getProperty(CONFIG_PROPERTY_TRACELOG);
return logEnabled || (globalProp != null && globalProp.booleanValue());
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wol...@us...> - 2012-05-29 16:13:54
|
Revision: 16499
http://exist.svn.sourceforge.net/exist/?rev=16499&view=rev
Author: wolfgang_m
Date: 2012-05-29 16:13:45 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[bugfix] Fixed util:inspect-function to properly report function arguments.
Modified Paths:
--------------
trunk/eXist/src/org/exist/xquery/functions/util/InspectFunction.java
Modified: trunk/eXist/src/org/exist/xquery/functions/util/InspectFunction.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/functions/util/InspectFunction.java 2012-05-29 16:11:28 UTC (rev 16498)
+++ trunk/eXist/src/org/exist/xquery/functions/util/InspectFunction.java 2012-05-29 16:13:45 UTC (rev 16499)
@@ -7,13 +7,6 @@
import org.exist.xquery.value.*;
import org.xml.sax.helpers.AttributesImpl;
-/**
- * Created with IntelliJ IDEA.
- * User: wolf
- * Date: 5/12/12
- * Time: 9:48 PM
- * To change this template use File | Settings | File Templates.
- */
public class InspectFunction extends BasicFunction {
public final static FunctionSignature signature =
@@ -79,10 +72,11 @@
attribs.clear();
attribs.addAttribute("", "type", "type", "CDATA", Type.getTypeName(type.getPrimaryType()));
attribs.addAttribute("", "cardinality", "cardinality", "CDATA", Cardinality.getDescription(type.getCardinality()));
+ if (type instanceof FunctionParameterSequenceType)
+ attribs.addAttribute("", "var", "var", "CDATA", ((FunctionParameterSequenceType)type).getAttributeName());
builder.startElement(ARGUMENT_QNAME, attribs);
if (type instanceof FunctionParameterSequenceType) {
- FunctionParameterSequenceType ftype = (FunctionParameterSequenceType) type;
- builder.characters(ftype.getAttributeName() + " " + ftype.getDescription());
+ builder.characters(((FunctionParameterSequenceType)type).getDescription());
}
builder.endElement();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wol...@us...> - 2012-05-29 16:11:39
|
Revision: 16498
http://exist.svn.sourceforge.net/exist/?rev=16498&view=rev
Author: wolfgang_m
Date: 2012-05-29 16:11:28 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[bugfix] NPE in dynamic function call.
Modified Paths:
--------------
trunk/eXist/src/org/exist/xquery/FunctionCall.java
Modified: trunk/eXist/src/org/exist/xquery/FunctionCall.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/FunctionCall.java 2012-05-29 16:10:08 UTC (rev 16497)
+++ trunk/eXist/src/org/exist/xquery/FunctionCall.java 2012-05-29 16:11:28 UTC (rev 16498)
@@ -129,7 +129,7 @@
* @see org.exist.xquery.Function#analyze(org.exist.xquery.AnalyzeContextInfo)
*/
public void analyze(AnalyzeContextInfo contextInfo) throws XPathException {
- updateFunction();
+ //updateFunction();
contextInfo.setParent(this);
AnalyzeContextInfo newContextInfo = new AnalyzeContextInfo(contextInfo);
newContextInfo.removeFlag(IN_NODE_CONSTRUCTOR);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wol...@us...> - 2012-05-29 16:10:20
|
Revision: 16497
http://exist.svn.sourceforge.net/exist/?rev=16497&view=rev
Author: wolfgang_m
Date: 2012-05-29 16:10:08 +0000 (Tue, 29 May 2012)
Log Message:
-----------
Updated demo app: new version of templating module uses introspection to inject request parameters into the template function.
Modified Paths:
--------------
apps/demo/build.xml
apps/demo/controller.xql
apps/demo/examples/urlrewriting/bad-page.html
apps/demo/examples/web/guess-templates.xql
apps/demo/examples/web/shakespeare.xql
apps/demo/modules/cex.xql
apps/demo/modules/config.xqm
apps/demo/modules/demo.xql
apps/demo/modules/i18n-templates.xql
apps/demo/modules/templates.xql
apps/demo/modules/view.xql
Modified: apps/demo/build.xml
===================================================================
--- apps/demo/build.xml 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/build.xml 2012-05-29 16:10:08 UTC (rev 16497)
@@ -5,4 +5,7 @@
<mkdir dir="${build.dir}"/>
<zip basedir="." destfile="${build.dir}/demo-0.1.xar" excludes="${build.dir}/*"/>
</target>
-</project>
\ No newline at end of file
+ <target name="clean">
+ <delete dir="${build.dir}"/>
+ </target>
+</project>
Modified: apps/demo/controller.xql
===================================================================
--- apps/demo/controller.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/controller.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -64,7 +64,6 @@
session:clear()
};
-
if ($logout) then
local:logout()
else
Modified: apps/demo/examples/urlrewriting/bad-page.html
===================================================================
--- apps/demo/examples/urlrewriting/bad-page.html 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/examples/urlrewriting/bad-page.html 2012-05-29 16:10:08 UTC (rev 16497)
@@ -4,7 +4,7 @@
<p>Submitting the form below should trigger a cast error in the XQuery script
on the server side (it expects a number). You should be redirected to the error handler
page.</p>
- <form>
+ <form method="GET">
<fieldset>
<label for="number">Enter a number</label>
<input name="number" size="20" value="ABCDEFG"/>
Modified: apps/demo/examples/web/guess-templates.xql
===================================================================
--- apps/demo/examples/web/guess-templates.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/examples/web/guess-templates.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -9,7 +9,7 @@
: and stores it into the session, then calls any nested templates with the
: generated number as $model.
:)
-declare function guess:init($node as node(), $params as element(parameters)?, $model as item()*) {
+declare function guess:init($node as node(), $model as item()*) {
session:create(),
let $randSession := session:get-attribute("random")
let $rand :=
@@ -24,8 +24,7 @@
(:~
: Evaluate the guessed number, which is passed in as model.
:)
-declare function guess:evaluate-guess($node as node(), $params as element(parameters)?, $random as xs:integer) {
- let $guess := request:get-parameter("guess", ())
+declare function guess:evaluate-guess($node as node(), $random as xs:integer, $guess as xs:integer) {
let $count as xs:integer := session:get-attribute("guesses") + 1
return (
session:set-attribute("guesses", $count),
Modified: apps/demo/examples/web/shakespeare.xql
===================================================================
--- apps/demo/examples/web/shakespeare.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/examples/web/shakespeare.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -11,11 +11,9 @@
Execute the query. The search results are not output immediately. Instead they
are passed to nested templates through the $model parameter.
:)
-declare function shakes:query($node as node()*, $params as element(parameters)?, $model as item()*) {
+declare function shakes:query($node as node()*, $model as item()*, $query as xs:string?, $mode as xs:string) {
session:create(),
- let $queryStr := request:get-parameter("query", ())
- let $mode := request:get-parameter("mode", "all")
- let $hits := shakes:do-query($queryStr, $mode)
+ let $hits := shakes:do-query($query, $mode)
let $store := session:set-attribute($shakes:SESSION, $hits)
return
(: Process nested templates :)
@@ -33,7 +31,7 @@
Read the last query result from the HTTP session and pass it to nested templates
in the $model parameter.
:)
-declare function shakes:from-session($node as node()*, $params as element(parameters)?, $model as item()*) {
+declare function shakes:from-session($node as node()*, $model as item()*) {
let $hits := session:get-attribute($shakes:SESSION)
return
templates:process($node/*, $hits)
@@ -42,15 +40,16 @@
(:~
Create a span with the number of items in the current search result.
:)
-declare function shakes:hit-count($node as node()*, $params as element(parameters)?, $model as item()*) {
+declare function shakes:hit-count($node as node()*, $model as item()*) {
<span id="hit-count">{ count($model) }</span>
};
(:~
Output the actual search result as a div, using the kwic module to summarize full text matches.
:)
-declare function shakes:show-hits($node as node()*, $params as element(parameters)?, $model as item()*) {
- let $start := number(request:get-parameter("start", 1))
+declare
+ %templates:default("start", 1)
+function shakes:show-hits($node as node()*, $model as item()*, $start as xs:int) {
for $hit at $p in subsequence($model, $start, 10)
let $kwic := kwic:summarize($hit, <config width="40" table="yes"/>, shakes:filter#2)
return
@@ -65,7 +64,7 @@
(:~
Callback function called from the kwic module.
:)
-declare function shakes:filter($node as node(), $mode as xs:string) as xs:string? {
+declare %private function shakes:filter($node as node(), $mode as xs:string) as xs:string? {
if ($node/parent::SPEAKER or $node/parent::STAGEDIR) then
()
else if ($mode eq 'before') then
@@ -74,13 +73,6 @@
concat(' ', $node)
};
-declare function shakes:create-query() {
- let $queryStr := request:get-parameter("query", ())
- let $mode := request:get-parameter("mode", "all")
- return
- shakes:create-query($queryStr, $mode)
-};
-
(:~
Helper function: create a lucene query from the user input
:)
Modified: apps/demo/modules/cex.xql
===================================================================
--- apps/demo/modules/cex.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/cex.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -4,10 +4,9 @@
import module namespace kwic="http://exist-db.org/xquery/kwic"
at "resource:org/exist/xquery/lib/kwic.xql";
-declare function cex:query($node as node()*, $params as element(parameters)?, $model as item()*) {
+declare function cex:query($node as node()*, $model as item()*, $query as xs:string?) {
<div class="cex-results">
{
- let $query := request:get-parameter("query", ())
for $result in ft:search("/db/", concat('page:', $query))/search
let $fields := $result/field
(: Retrieve title from title field if available :)
Modified: apps/demo/modules/config.xqm
===================================================================
--- apps/demo/modules/config.xqm 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/config.xqm 2012-05-29 16:10:08 UTC (rev 16497)
@@ -43,7 +43,7 @@
: For debugging: generates a table showing all properties defined
: in the application descriptors.
:)
-declare function config:app-info($node as node(), $params as element(parameters)?, $model as item()*) {
+declare function config:app-info($node as node(), $model as item()*) {
let $expath := config:expath-descriptor()
let $repo := config:repo-descriptor()
return
Modified: apps/demo/modules/demo.xql
===================================================================
--- apps/demo/modules/demo.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/demo.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -3,31 +3,50 @@
import module namespace t="http://exist-db.org/apps/demo/shakespeare/tests" at "xmldb:exist:///db/demo/examples/tests/shakespeare-tests.xql";
import module namespace test="http://exist-db.org/xquery/xqsuite" at "xmldb:exist:///db/xqsuite.xql";
-declare function demo:hello($node as node()*, $params as element(parameters)?, $model as item()*) {
+(:~
+ : Simple templating function. A templating function needs to take two parameters at least.
+ : It may return any sequence, which will be inserted into the output instead of $node.
+ :
+ : @param $node the HTML node which contained the class attribute which triggered this call.
+ : @param $model an arbitrary sequence of items. Use this to pass required information between
+ : tempate functions.
+ :)
+declare function demo:hello($node as node()*, $model as item()*) as element(span) {
<span>Hello World!</span>
};
-declare function demo:multiply($node as node()*, $params as element(parameters)?, $model as item()*) {
- let $p1 := $params/param[@name = "n1"]/@value
- let $p2 := $params/param[@name = "n2"]/@value
- return
- number($p1) * number($p2)
+(:~
+ : A templating function taking two additional parameters. The templating framework inspects
+ : the function signature and tries to fill in additional parameters automatically. The value
+ : to use is determined as follows:
+ :
+ : <ol>
+ : <li>if there's a (non-empty) request parameter with the same name as the variable, use it</li>
+ : <li>check for a parameter with the same name in the parameters list given in the call to
+ : the templating function.</li>
+ : <li>test if there's an annotation %templating:default(name, value) whose first parameter matches
+ : the name of the parameter variable. Use the second parameter as value if it does.</li>
+ : </ol>
+ :)
+declare function demo:multiply($node as node()*, $model as item()*, $n1 as xs:int, $n2 as xs:int) {
+ $p1 * $p2
};
-declare function demo:error-handler-test($node as node(), $params as element(parameters)?, $model as item()*) {
- let $input as xs:integer? := request:get-parameter("number", ())
- return
- $input
+declare function demo:error-handler-test($node as node(), $model as item()*, $number as xs:string?) {
+ if (exists($number)) then
+ xs:int($number)
+ else
+ ()
};
-declare function demo:link-to-home($node as node(), $params as element(parameters)?, $model as item()*) {
+declare function demo:link-to-home($node as node(), $model as item()*) {
<a href="{request:get-context-path()}/">{
$node/@* except $node/@href,
$node/node()
}</a>
};
-declare function demo:run-tests($node as node(), $params as element(parameters)?, $model as item()*) {
+declare function demo:run-tests($node as node(), $model as item()*) {
let $results := test:suite(util:list-functions("http://exist-db.org/apps/demo/shakespeare/tests"))
return
test:to-html($results)
Modified: apps/demo/modules/i18n-templates.xql
===================================================================
--- apps/demo/modules/i18n-templates.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/i18n-templates.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -13,9 +13,7 @@
: lang=de Language selection
: catalogues=relative path Path to the i18n catalogue XML files inside database
:)
-declare function intl:translate($node as node(), $params as element(parameters)?, $model as item()*) {
- let $selectedLang := $params/param[@name = "lang"]/@value
- let $catalogues := $params/param[@name = "catalogues"]/@value
+declare function intl:translate($node as node(), $model as item()*, $lang as xs:string, $catalogues as xs:string) {
let $cpath :=
(: if path to catalogues is relative, resolve it relative to the app root :)
if (starts-with($catalogues, "/")) then
@@ -23,7 +21,7 @@
else
concat($config:app-root, "/", $catalogues)
let $translated :=
- i18n:process($node/*, $selectedLang, $cpath, ())
+ i18n:process($node/*, $lang, $cpath, ())
return
element { node-name($node) } {
$node/@*,
Modified: apps/demo/modules/templates.xql
===================================================================
--- apps/demo/modules/templates.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/templates.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -8,6 +8,7 @@
import module namespace config="http://exist-db.org/xquery/apps/config" at "config.xqm";
declare variable $templates:NOT_FOUND := QName("http://exist-db.org/xquery/templates", "NotFound");
+declare variable $templates:TOO_MANY_ARGS := QName("http://exist-db.org/xquery/templates", "TooManyArguments");
(:~
: Start processing the provided content. Template functions are looked up by calling the
@@ -44,7 +45,7 @@
templates:process($node, $resolver, $model)
};
-declare function templates:process($node as node(), $resolver as function(xs:string) as item()?, $model as item()*) {
+declare %private function templates:process($node as node(), $resolver as function(xs:string) as item()?, $model as item()*) {
typeswitch ($node)
case document-node() return
for $child in $node/node() return templates:process($child, $resolver, $model)
@@ -63,21 +64,21 @@
$node
};
-declare function templates:get-instructions($class as xs:string?) as xs:string* {
+declare %private function templates:get-instructions($class as xs:string?) as xs:string* {
for $name in tokenize($class, "\s+")
where templates:is-qname($name)
return
$name
};
-declare function templates:call($class as xs:string, $node as element(), $model as item()*, $resolver as function(xs:string) as item()?) {
+declare %private function templates:call($class as xs:string, $node as element(), $model as item()*, $resolver as function(xs:string) as item()?) {
let $paramStr := substring-after($class, "?")
let $parameters := templates:parse-parameters($paramStr)
let $func := if ($paramStr) then substring-before($class, "?") else $class
- let $call := $resolver($func)
+ let $call := templates:resolve(10, $func, $resolver)
return
if (exists($call)) then
- $call($node, $parameters, $model)
+ templates:call-by-introspection($node, $parameters, $model, $call)
else
(: Templating function not found: just copy the element :)
element { node-name($node) } {
@@ -85,7 +86,93 @@
}
};
-declare function templates:parse-parameters($paramStr as xs:string?) as element(parameters) {
+declare %private function templates:call-by-introspection($node as element(), $parameters as element(parameters), $model as item()*,
+ $fn as function(*)) {
+ let $inspect := util:inspect-function($fn)
+ let $args := templates:map-arguments($inspect, $parameters)
+ return
+ templates:call-with-args($fn, $args, $node, $model)
+};
+
+declare %private function templates:call-with-args($fn as function(*), $args as (function() as item()*)*,
+ $node as element(), $model as item()*) {
+ switch (count($args))
+ case 0 return
+ $fn($node, $model)
+ case 1 return
+ $fn($node, $model, $args[1]())
+ case 2 return
+ $fn($node, $model, $args[1](), $args[2]())
+ case 3 return
+ $fn($node, $model, $args[1](), $args[2](), $args[3]())
+ case 4 return
+ $fn($node, $model, $args[1](), $args[2](), $args[3](), $args[4]())
+ case 5 return
+ $fn($node, $model, $args[1](), $args[2](), $args[3](), $args[4](), $args[5]())
+ case 6 return
+ $fn($node, $model, $args[1](), $args[2](), $args[3](), $args[4](), $args[5](), $args[6]())
+ default return
+ error($templates:TOO_MANY_ARGS, "Too many arguments to function " || function-name($fn))
+};
+
+declare %private function templates:map-arguments($inspect as element(function), $parameters as element(parameters)) {
+ let $args := $inspect/argument
+ return
+ if (count($args) > 2) then
+ for $arg in subsequence($inspect/argument, 3)
+ return
+ templates:map-argument($arg, $parameters)
+ else
+ ()
+};
+
+declare %private function templates:map-argument($arg as element(argument), $parameters as element(parameters))
+ as function() as item()* {
+ let $var := $arg/@var
+ let $type := $arg/@type/string()
+ let $param :=
+ string((
+ request:get-parameter($var, ()),
+ $parameters/param[@name = $var]/@value,
+ templates:arg-from-annotation($var, $arg)
+ )[1])
+ let $data :=
+ try {
+ templates:cast($param, $type)
+ } catch * {
+ error($templates:TYPE_ERROR, "Failed to cast parameter value '" || $param || "' to the required target type for " ||
+ "template function parameter $" || $name || " of function " || ($arg/../@name) || ". Required type was: " ||
+ $type || ". " || $err:description)
+ }
+ return
+ function() {
+ $data
+ }
+};
+
+declare function templates:arg-from-annotation($var as xs:string, $arg as element(argument)) {
+ let $anno :=
+ $arg/../annotation[ends-with(@name, ":default")]
+ [@namespace = "http://exist-db.org/xquery/templates"]
+ [value[1] = $var]
+ return
+ string($anno/value[2])
+};
+
+declare %private function templates:resolve($arity as xs:int, $func as xs:string,
+ $resolver as function(xs:string, xs:int) as function(*)) {
+ if ($arity < 2) then
+ ()
+ else
+ let $fn := $resolver($func, $arity)
+ return
+ if (exists($fn)) then
+ $fn
+ else
+ templates:resolve($arity - 1, $func, $resolver)
+};
+
+declare %private function templates:parse-parameters($paramStr as xs:string?) as element(parameters) {
<parameters>
{
for $param in tokenize($paramStr, "&")
@@ -98,21 +185,51 @@
</parameters>
};
-declare function templates:is-qname($class as xs:string) as xs:boolean {
+declare %private function templates:is-qname($class as xs:string) as xs:boolean {
matches($class, "^[^:]+:[^:]+")
};
-declare function templates:include($node as node(), $params as element(parameters)?, $model as item()*) {
- let $relPath := $params/param[@name = "path"]/@value
- let $path := concat($config:app-root, "/", $relPath)
+declare %private function templates:cast($values as item()*, $targetType as xs:string) {
+ for $value in $values
return
+ if ($targetType != "xs:string" and string-length($value) = 0) then
+ (: treat "" as empty sequence :)
+ ()
+ else
+ switch ($targetType)
+ case "xs:string" return
+ string($value)
+ case "xs:integer" case "xs:int" case "xs:long" return
+ xs:integer($value)
+ case "xs:decimal" return
+ xs:decimal($value)
+ case "xs:float" case "xs:double" return
+ xs:double($value)
+ case "xs:date" return
+ xs:date($value)
+ case "xs:dateTime" return
+ xs:dateTime($value)
+ case "xs:time" return
+ xs:time($value)
+ case "element()" return
+ util:parse($value)/*
+ case "text()" return
+ text { string($value) }
+ default return
+ $value
+};
+
+(:-----------------------------------------------------------------------------------
+ : Standard templates
+ :-----------------------------------------------------------------------------------:)
+
+declare function templates:include($node as node(), $model as item()*, $path as xs:string) {
+ let $path := concat($config:app-root, "/", $path)
+ return
templates:process(doc($path), $model)
};
-declare function templates:surround($node as node(), $params as element(parameters)?, $model as item()*) {
- let $with := $params/param[@name = "with"]/@value
- let $at := $params/param[@name = "at"]/@value
- let $using := $params/param[@name = "using"]/@value
+declare function templates:surround($node as node(), $model as item()*, $with as xs:string, $at as xs:string?, $using as xs:string?) {
let $path := concat($config:app-root, "/", $with)
let $content :=
if ($using) then
@@ -141,9 +258,8 @@
$node
};
-declare function templates:if-parameter-set($node as node(), $params as element(parameters), $model as item()*) as node()* {
- let $paramName := $params/param[@name = "param"]/@value/string()
- let $param := request:get-parameter($paramName, ())
+declare function templates:if-parameter-set($node as node(), $model as item()*, $param as xs:string) as node()* {
+ let $param := request:get-parameter($param, ())
return
if ($param and string-length($param) gt 0) then
templates:process($node/node(), $model)
@@ -151,9 +267,8 @@
()
};
-declare function templates:if-parameter-unset($node as node(), $params as element(parameters), $model as item()*) as node()* {
- let $paramName := $params/param[@name = "param"]/@value/string()
- let $param := request:get-parameter($paramName, ())
+declare function templates:if-parameter-unset($node as node(), $model as item()*, $param as xs:string) as node()* {
+ let $param := request:get-parameter($param, ())
return
if (not($param) or string-length($param) eq 0) then
$node
@@ -161,26 +276,22 @@
()
};
-declare function templates:if-module-missing($node as node(), $params as element(parameters)?, $model as item()*) {
- let $at := $params/param[@name = "at"]/@value/string()
- let $uri := $params/param[@name = "uri"]/@value/string()
- return
- try {
- util:import-module($uri, "testmod", $at)
- } catch * {
- (: Module was not found: process content :)
- templates:process($node/node(), $model)
- }
+declare function templates:if-module-missing($node as node(), $model as item()*, $uri as xs:string, $at as xs:string) {
+ try {
+ util:import-module($uri, "testmod", $at)
+ } catch * {
+ (: Module was not found: process content :)
+ templates:process($node/node(), $model)
+ }
};
-declare function templates:display-source($node as node(), $params as element(parameters)?, $model as item()*) {
- let $syntax := $params/param[@name = "lang"]/@value/string()
+declare function templates:display-source($node as node(), $model as item()*, $lang as xs:string?) {
let $source := replace($node/string(), "^\s*(.*)\s*$", "$1")
let $context := request:get-context-path()
let $eXidePath := if (doc-available("/db/eXide/index.html")) then "apps/eXide" else "eXide"
return
<div class="code">
- <pre class="brush: {if ($syntax) then $syntax else 'xquery'}">
+ <pre class="brush: {if ($lang) then $lang else 'xquery'}">
{ $source }
</pre>
<a class="btn" href="{$context}/{$eXidePath}/index.html?snip={encode-for-uri($source)}" target="eXide"
@@ -188,7 +299,7 @@
</div>
};
-declare function templates:load-source($node as node(), $params as element(parameters), $model as item()*) as node()* {
+declare function templates:load-source($node as node(), $model as item()*) as node()* {
let $href := $node/@href/string()
let $context := request:get-context-path()
let $eXidePath := if (doc-available("/db/eXide/index.html")) then "apps/eXide" else "eXide"
@@ -200,7 +311,7 @@
Processes input and select form controls, setting their value/selection to
values found in the request - if present.
:)
-declare function templates:form-control($node as node(), $params as element(parameters), $model as item()*) as node()* {
+declare function templates:form-control($node as node(), $model as item()*) as node()* {
typeswitch ($node)
case element(input) return
let $name := $node/@name
@@ -236,7 +347,7 @@
$node
};
-declare function templates:error-description($node as node(), $params as element(parameters)?, $model as item()*) {
+declare function templates:error-description($node as node(), $model as item()*) {
let $input := request:get-attribute("org.exist.forward.error")
return
element { node-name($node) } {
@@ -245,8 +356,7 @@
}
};
-declare function templates:fix-links($node as node(), $params as element(parameters)?, $model as item()*) {
- let $root := $params/param[@name = "root"]/@value/string()
+declare function templates:fix-links($node as node(), $model as item()*, $root as xs:string) {
let $prefix :=
if ($root eq "context") then
request:get-context-path()
Modified: apps/demo/modules/view.xql
===================================================================
--- apps/demo/modules/view.xql 2012-05-29 15:37:25 UTC (rev 16496)
+++ apps/demo/modules/view.xql 2012-05-29 16:10:08 UTC (rev 16497)
@@ -12,9 +12,9 @@
declare option exist:serialize "method=html5 media-type=text/html";
-let $lookup := function($functionName as xs:string) {
+let $lookup := function($functionName as xs:string, $arity as xs:int) {
try {
- function-lookup(xs:QName($functionName), 3)
+ function-lookup(xs:QName($functionName), $arity)
} catch * {
()
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-29 15:37:36
|
Revision: 16496
http://exist.svn.sourceforge.net/exist/?rev=16496&view=rev
Author: shabanovd
Date: 2012-05-29 15:37:25 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[ignore] fix broken test
Modified Paths:
--------------
trunk/eXist/src/org/exist/xquery/TryCatchExpression.java
Modified: trunk/eXist/src/org/exist/xquery/TryCatchExpression.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/TryCatchExpression.java 2012-05-29 15:00:17 UTC (rev 16495)
+++ trunk/eXist/src/org/exist/xquery/TryCatchExpression.java 2012-05-29 15:37:25 UTC (rev 16496)
@@ -138,6 +138,8 @@
// if no errorcode is found, reconstruct by parsing the error text.
if (errorCode == null) {
errorCode = extractErrorCode(xpe);
+ } else if (errorCode == ErrorCodes.ERROR) {
+ errorCode = extractErrorCode(xpe);
}
} else {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-29 15:00:27
|
Revision: 16495
http://exist.svn.sourceforge.net/exist/?rev=16495&view=rev
Author: shabanovd
Date: 2012-05-29 15:00:17 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[ignore] avoid NPE
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java
trunk/eXist/src/org/exist/xquery/functions/xmldb/XMLDBAuthenticate.java
Modified: trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java 2012-05-29 14:36:39 UTC (rev 16494)
+++ trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java 2012-05-29 15:00:17 UTC (rev 16495)
@@ -390,7 +390,7 @@
}
@Override
- public Subject authenticate(String username, final Object credentials) throws AuthenticationException {
+ public Subject authenticate(final String username, final Object credentials) throws AuthenticationException {
if (LOG.isDebugEnabled())
LOG.debug("Authentication try for '"+username+"'.");
Modified: trunk/eXist/src/org/exist/xquery/functions/xmldb/XMLDBAuthenticate.java
===================================================================
--- trunk/eXist/src/org/exist/xquery/functions/xmldb/XMLDBAuthenticate.java 2012-05-29 14:36:39 UTC (rev 16494)
+++ trunk/eXist/src/org/exist/xquery/functions/xmldb/XMLDBAuthenticate.java 2012-05-29 15:00:17 UTC (rev 16495)
@@ -140,6 +140,11 @@
String uri = args[0].getStringValue();
String userName = args[1].getStringValue();
+ if (userName == null) {
+ logger.error("Unable to authenticate username == NULL");
+ return BooleanValue.FALSE;
+ }
+
String password = args[2].getStringValue();
boolean createSession = false;
@@ -177,7 +182,7 @@
}
if( isCalledAs( "login" ) ) {
- context.getBroker().setUser( user );
+ context.getBroker().setSubject( user );
/** if there is a http session cache the user in the http session */
cacheUserInHttpSession( user, createSession );
@@ -211,7 +216,6 @@
}
}
-
/**
* Get the HTTP Session variable. Create it if requested and it doesn't exist.
*
@@ -246,8 +250,6 @@
var = sessionModule.declareVariable( SessionModule.SESSION_VAR, session );
}
}
-
return( var );
}
-
-}
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-29 14:36:48
|
Revision: 16494
http://exist.svn.sourceforge.net/exist/?rev=16494&view=rev
Author: shabanovd
Date: 2012-05-29 14:36:39 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[ignore] avoid username change during authentication
Modified Paths:
--------------
trunk/eXist/extensions/security/activedirectory/src/org/exist/security/realm/activedirectory/ActiveDirectoryRealm.java
trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
trunk/eXist/extensions/security/oauth/src/org/exist/security/realm/oauth/OAuthRealm.java
trunk/eXist/extensions/security/openid/src/org/exist/security/realm/openid/OpenIDRealm.java
trunk/eXist/src/org/exist/security/internal/RealmImpl.java
trunk/eXist/src/org/exist/security/realm/AuthenticatingRealm.java
Modified: trunk/eXist/extensions/security/activedirectory/src/org/exist/security/realm/activedirectory/ActiveDirectoryRealm.java
===================================================================
--- trunk/eXist/extensions/security/activedirectory/src/org/exist/security/realm/activedirectory/ActiveDirectoryRealm.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/extensions/security/activedirectory/src/org/exist/security/realm/activedirectory/ActiveDirectoryRealm.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -96,7 +96,7 @@
* java.lang.Object)
*/
@Override
- public Subject authenticate(String username, Object credentials) throws AuthenticationException {
+ public Subject authenticate(final String username, Object credentials) throws AuthenticationException {
String returnedAtts[] = { "sn", "givenName", "mail" };
String searchFilter = "(&(objectClass=user)(sAMAccountName=" + username + "))";
Modified: trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java
===================================================================
--- trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/extensions/security/ldap/src/org/exist/security/realm/ldap/LDAPRealm.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -108,26 +108,26 @@
private String ensureCase(String username) {
if(principalsAreCaseInsensitive) {
- username = username.toLowerCase();
+ return username.toLowerCase();
}
return username;
}
@Override
- public Subject authenticate(String username, Object credentials) throws AuthenticationException {
+ public Subject authenticate(final String username, Object credentials) throws AuthenticationException {
- username = ensureCase(username);
+ String name = ensureCase(username);
// Binds using the username and password provided by the user.
LdapContext ctx = null;
try {
- ctx = ensureContextFactory().getLdapContext(username, String.valueOf(credentials));
+ ctx = ensureContextFactory().getLdapContext(name, String.valueOf(credentials));
- AbstractAccount account = (AbstractAccount) getAccount(ctx, username);
+ AbstractAccount account = (AbstractAccount) getAccount(ctx, name);
if (account == null)
throw new AuthenticationException(
AuthenticationException.ACCOUNT_NOT_FOUND,
- "Account '"+username+"' can not be found.");
+ "Account '"+name+"' can not be found.");
return new AuthenticatedLdapSubjectAccreditedImpl(account, ctx, String.valueOf(credentials));
Modified: trunk/eXist/extensions/security/oauth/src/org/exist/security/realm/oauth/OAuthRealm.java
===================================================================
--- trunk/eXist/extensions/security/oauth/src/org/exist/security/realm/oauth/OAuthRealm.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/extensions/security/oauth/src/org/exist/security/realm/oauth/OAuthRealm.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -109,8 +109,7 @@
}
@Override
- public Subject authenticate(String accountName, Object credentials) throws AuthenticationException {
- // Auto-generated method stub
+ public Subject authenticate(final String accountName, Object credentials) throws AuthenticationException {
return null;
}
Modified: trunk/eXist/extensions/security/openid/src/org/exist/security/realm/openid/OpenIDRealm.java
===================================================================
--- trunk/eXist/extensions/security/openid/src/org/exist/security/realm/openid/OpenIDRealm.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/extensions/security/openid/src/org/exist/security/realm/openid/OpenIDRealm.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -66,8 +66,7 @@
}
@Override
- public Subject authenticate(String accountName, Object credentials) throws AuthenticationException {
- // TODO Auto-generated method stub
+ public Subject authenticate(final String accountName, Object credentials) throws AuthenticationException {
return null;
}
Modified: trunk/eXist/src/org/exist/security/internal/RealmImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/src/org/exist/security/internal/RealmImpl.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -261,7 +261,7 @@
}
@Override
- public Subject authenticate(String accountName, Object credentials) throws AuthenticationException {
+ public Subject authenticate(final String accountName, Object credentials) throws AuthenticationException {
final Account account = getAccount(accountName);
if(account == null) {
Modified: trunk/eXist/src/org/exist/security/realm/AuthenticatingRealm.java
===================================================================
--- trunk/eXist/src/org/exist/security/realm/AuthenticatingRealm.java 2012-05-29 14:01:30 UTC (rev 16493)
+++ trunk/eXist/src/org/exist/security/realm/AuthenticatingRealm.java 2012-05-29 14:36:39 UTC (rev 16494)
@@ -30,6 +30,6 @@
*/
public interface AuthenticatingRealm {
- Subject authenticate(String accountName, Object credentials) throws AuthenticationException;
+ Subject authenticate(final String accountName, Object credentials) throws AuthenticationException;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sha...@us...> - 2012-05-29 14:01:41
|
Revision: 16493
http://exist.svn.sourceforge.net/exist/?rev=16493&view=rev
Author: shabanovd
Date: 2012-05-29 14:01:30 +0000 (Tue, 29 May 2012)
Log Message:
-----------
[ignore] avoid NPE when authenticate with username == NULL
Modified Paths:
--------------
trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java
Modified: trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java
===================================================================
--- trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java 2012-05-29 13:54:52 UTC (rev 16492)
+++ trunk/eXist/src/org/exist/security/internal/SecurityManagerImpl.java 2012-05-29 14:01:30 UTC (rev 16493)
@@ -394,7 +394,11 @@
if (LOG.isDebugEnabled())
LOG.debug("Authentication try for '"+username+"'.");
- if("jsessionid".equals(username)) {
+ if (username == null)
+ throw new AuthenticationException(
+ AuthenticationException.ACCOUNT_NOT_FOUND, "Account NULL not found");
+
+ if("jsessionid".equals(username)) {
if (getSystemSubject().getSessionId().equals(credentials))
return getSystemSubject();
@@ -447,7 +451,9 @@
LOG.debug("Account '"+username+"' not found, throw error");
}
- throw new AuthenticationException(AuthenticationException.ACCOUNT_NOT_FOUND, "User [" + username + "] not found");
+ throw new AuthenticationException(
+ AuthenticationException.ACCOUNT_NOT_FOUND,
+ "Account [" + username + "] not found");
}
protected Subject systemSubject = null;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|