|
From: <th...@us...> - 2004-01-07 10:59:31
|
Update of /cvsroot/jaxme/JaxMe/src/runtime/de/ispsoft/jaxme/tamino
In directory sc8-pr-cvs1:/tmp/cvs-serv18038/src/runtime/de/ispsoft/jaxme/tamino
Modified Files:
InoResponseHandlerNoNs.java InoManagerNoNs.java
Log Message:
extended cursoring and bugfixes
Index: InoResponseHandlerNoNs.java
===================================================================
RCS file: /cvsroot/jaxme/JaxMe/src/runtime/de/ispsoft/jaxme/tamino/InoResponseHandlerNoNs.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- InoResponseHandlerNoNs.java 6 Jan 2004 10:24:58 -0000 1.1
+++ InoResponseHandlerNoNs.java 7 Jan 2004 10:59:28 -0000 1.2
@@ -10,6 +10,8 @@
import org.apache.log4j.Category;
+import de.ispsoft.jaxme.ResultInfo;
+
/** <p>This is a SAX content handler for an ino:response document. It
* provides a special handling for mapping the ino:id attribute to a
* configurable attribute of the element class. This can be useful if the
@@ -49,10 +51,13 @@
private String targetNamespace = null;
private int i;
+
+ private ResultInfo resultInfo = null;
/** Creates a new InoResponseHandler */
public InoResponseHandlerNoNs() {}
+
/**
* Configure an ino:id mapping attribute. The first param idAttribute
* provides the attributes name used in the JMAnyElement instance as id.
@@ -139,6 +144,10 @@
}
} else if (inoObjectIdList != null && "object".equals(localName)) {
inoObjectIdList.add(attr.getValue(INO_RESPONSE2_URI, "id"));
+ } if ("cursor".equals(localName)) {
+ String cc = attr.getValue(INO_RESPONSE2_URI, "count");
+ if(resultInfo != null && cc != null && cc.length() > 0)
+ resultInfo.setCursorCount(Integer.parseInt(cc));
}
}
}
@@ -278,4 +287,18 @@
* @see #setInoObjectIdList
*/
public List getInoObjectIdList() { return inoObjectIdList; }
+ /**
+ * @return
+ */
+ public ResultInfo getResultInfo() {
+ return resultInfo;
+ }
+
+ /**
+ * @param info
+ */
+ public void setResultInfo(ResultInfo info) {
+ resultInfo = info;
+ }
+
}
Index: InoManagerNoNs.java
===================================================================
RCS file: /cvsroot/jaxme/JaxMe/src/runtime/de/ispsoft/jaxme/tamino/InoManagerNoNs.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- InoManagerNoNs.java 6 Jan 2004 10:24:58 -0000 1.1
+++ InoManagerNoNs.java 7 Jan 2004 10:59:28 -0000 1.2
@@ -9,6 +9,7 @@
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
@@ -28,7 +29,7 @@
import de.ispsoft.jaxme.JMManagerImpl;
import de.ispsoft.jaxme.JMManagerFactoryImpl;
import de.ispsoft.jaxme.Observer;
-
+import de.ispsoft.jaxme.ResultInfo;
/** <p>An implementation of a JMManager for a Tamino database. This
* InoManager handles the tamino db access without namespace support.
@@ -49,6 +50,30 @@
* and map the ino:id attribute to inoid without an attribute namespace. The
* targetnamespace for incomming xml documents from database is set to
* http://my.namespace.com/data.
+ *
+ * Cursoring is possible in two ways:
+ *
+ * (a)
+ * 1. Open session:
+ * http://host:port/tamino/DB/col?_connect=*
+ * 2. Query:
+ * http://host:port/tamino/DB/col?_cursor=open&_count=cheap&_sessionid=XYZ&_sessionkey=ABCD&_xql=Query
+ * 3. Daten abfragen:
+ * http://host:port/tamino/DB/col?_cursor=fetch&_handle=1&_position=10&_quantity=5&_sessionid=XYZ_sessionkey=HIJK
+ * 4. Close Session:
+ * http://host:port/tamino/DB/col?_disconnect=*&_sessionid=XYZ&sessionkey=STUV
+ *
+ * (b)
+ * By combining the _cursor=open command with the query, the query is executed
+ * outside a tamino session and the (cursoring) command can be executed without
+ * session handling and/or closing cursor.
+ *
+ * http://host:port/tamino/DB/col?_cursor=open&_count=cheap&_xql=Query&_position=POS&_quantity=QU
+ *
+ * Because of it's simplicity the second option is used and can be activated
+ * by the configuration flag <Use-Cursoring>yes</Use-Cursoring>. By default this
+ * special cursoring is not used.
+ *
*</p>
* @see de.ispsoft.jaxme.XMLSerializerNoNS
* @see de.ispsoft.jaxme.InoResponseHandlerNoNS
@@ -56,318 +81,368 @@
* @author <a href="mailto:hae...@gm...">Thomas Haenel</a>
*/
public class InoManagerNoNs extends JMManagerImpl {
-
- private static final Category cat = Category.getInstance(InoManagerNoNs.class.getName());
- private URL dbURL;
- private String user;
- private String password;
- private boolean useGet;
- private SAXParserFactory spf;
- private String idAttribute = null;
- private String idAttributeNS = null;
- private String targetNamespaceIn = null;
+ private static final Category cat = Category.getInstance(InoManagerNoNs.class.getName());
- /** <p>Name of our private configuration node (<samp>InoManager</samp> in
- * namespace <code>JMManagerFactoryImpl.NAMESPACE_URI</code>)</p>
- */
- public static final String CONFIGURATION_NODE_NAME = "InoManager";
- /** <p>Name of the database URL node, including the collection name.</p>
- */
- public static final String DBURL_NODE_NAME = "DbURL";
- /** <p>Name of the User node</p>
- */
- public static final String USER_NODE_NAME = "User";
- /** <p>Name of the Password node</p>
- */
- public static final String PASSWORD_NODE_NAME = "Password";
- /** <p>Name of the attribute Id mapping. By default
- * no mapping is used.</p>
- */
- public static final String ID_ATTRIBUTE = "Id-Attribute";
- /** <p>The namespace for the mapped attribute. By default
- * no mapping is used.</p>
- */
- public static final String ID_ATTRIBUTE_NS = "Id-Attribute-NS";
- /** <p>The namespace to use for incomming documents from tamino db.
- * By default no namespace is used.</p>
- */
- public static final String TARGETNAMESPACE_IN = "TargetNamespace-IN";
+ private URL dbURL;
+ private String user;
+ private String password;
+ private boolean useGet;
+ private SAXParserFactory spf;
+ private String idAttribute = null;
+ private String idAttributeNS = null;
+ private String targetNamespaceIn = null;
+ private boolean useCursoring = false;
+
+ /** <p>Name of our private configuration node (<samp>InoManager</samp> in
+ * namespace <code>JMManagerFactoryImpl.NAMESPACE_URI</code>)</p>
+ */
+ public static final String CONFIGURATION_NODE_NAME = "InoManager";
+
+ /** <p>Name of the database URL node, including the collection name.</p>
+ */
+ public static final String DBURL_NODE_NAME = "DbURL";
+ /** <p>Name of the User node</p>
+ */
+ public static final String USER_NODE_NAME = "User";
+ /** <p>Name of the Password node</p>
+ */
+ public static final String PASSWORD_NODE_NAME = "Password";
- /** <p>Returns the element ID. The default implementation
- * returns
- * <code>getAttribute(InoResponseHandler.INO_RESPONSE2_URI, "id")</code>.
- * If you use another element as the ID, change this.</p>
- */
- protected String getElementId(JMAnyElement pElement) throws SAXException {
- if(idAttribute != null) {
- String id = pElement.getAttribute(idAttributeNS, idAttribute, null);
- pElement.removeAttribute(idAttributeNS, idAttribute);
- return id;
- } else
- return pElement.getAttribute(InoResponseHandlerNoNs.INO_RESPONSE2_URI, "id", null);
- }
+ /** <p>Name of the attribute Id mapping. By default
+ * no mapping is used.</p>
+ */
+ public static final String ID_ATTRIBUTE = "Id-Attribute";
- /** <p>After an insert, sets the elements ID. The default
- * implementation performs
- * <code>setAttribute(InoResponseHandler.INO_RESPONSE2_URI, "id", pId)</code>.
- * If you use another element as the ID, change this. You probably need
- * to read the inserted document by using the supplied ino:id.</p>
- */
- protected void setElementId(JMAnyElement pElement, String pId) throws SAXException {
- pElement.setAttribute(InoResponseHandlerNoNs.INO_RESPONSE2_URI, "id", pId, null);
- if(idAttribute != null) {
- pElement.setAttribute(idAttributeNS, idAttribute, pId, null);
- }
- }
+ /** <p>The namespace for the mapped attribute. By default
+ * no mapping is used.</p>
+ */
+ public static final String ID_ATTRIBUTE_NS = "Id-Attribute-NS";
- /** <p>Returns a query suited for deleting the element.</p>
- */
- protected String getDeleteQuery(JMAnyElement pElement) throws SAXException {
- String id = getElementId(pElement);
- if (id == null || id.length() == 0) {
- throw new SAXException("The element being deleted doesn't have an ID.");
- }
- return "_delete=" +
- URLEncoder.encode(pElement.getLocalName() + "[@ino:id=" + id + "]");
- }
+ /** <p>The namespace to use for incomming documents from tamino db.
+ * By default no namespace is used.</p>
+ */
+ public static final String TARGETNAMESPACE_IN = "TargetNamespace-IN";
- /** <p>Returns a query suited for updating the element.</p>
- */
- protected String getUpdateQuery(JMAnyElement pElement) throws SAXException {
- String id = getElementId(pElement);
- if (id == null || id.length() == 0) {
- throw new SAXException("The element being updated doesn't have an ID.");
+ /** <p>Use the special cursoring as described above.</p>
+ */
+ public static final String USE_CURSORING = "Use-Cursoring";
+
+ /**
+ * @return
+ */
+ public URL getDbURL() {
+ return dbURL;
}
- return "_process=" + URLEncoder.encode(pElement.toXMLNoNS());
- }
- /** <p>Returns a query suited for inserting the element.</p>
- */
- protected String getInsertQuery(JMAnyElement pElement) throws SAXException {
- String id = getElementId(pElement);
- if (id != null && id.length() > 0) {
- throw new SAXException("The element being inserted already has an ID.");
+ /**
+ * @param url
+ */
+ public void setDbURL(URL url) {
+ dbURL = url;
}
- return "_process=" + URLEncoder.encode(pElement.toXMLNoNS());
- }
- /** <p>Parses a configuration element. This method is called twice:
- * Once for the default configuration and once for the specific
- * configuration.</p>
- */
- public void parseConfiguration(Element pElement) {
- super.parseConfiguration(pElement);
- for (Node node = pElement.getFirstChild();
- node != null;
- node = node.getNextSibling()) {
- if (node.getNodeType() == Node.ELEMENT_NODE &&
- JMManagerFactoryImpl.NAMESPACE_URI.equals(node.getNamespaceURI())) {
- if (CONFIGURATION_NODE_NAME.equals(node.getLocalName())) {
- for (Node child = node.getFirstChild();
- child != null;
- child = child.getNextSibling()) {
- if (child.getNodeType() == Node.ELEMENT_NODE &&
- JMManagerFactoryImpl.NAMESPACE_URI.equals(child.getNamespaceURI())) {
- if (DBURL_NODE_NAME.equals(child.getLocalName())) {
- String url = JMManagerFactoryImpl.getNodeText(child);
- try {
- dbURL = new java.net.URL(url);
- } catch (MalformedURLException e) {
- throw new IllegalArgumentException("Invalid database URL: " + url);
+ /** <p>Parses a configuration element. This method is called twice:
+ * Once for the default configuration and once for the specific
+ * configuration.</p>
+ */
+ public void parseConfiguration(Element pElement) {
+ super.parseConfiguration(pElement);
+ for (Node node = pElement.getFirstChild();
+ node != null;
+ node = node.getNextSibling()) {
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && JMManagerFactoryImpl.NAMESPACE_URI.equals(node.getNamespaceURI())) {
+ if (CONFIGURATION_NODE_NAME.equals(node.getLocalName())) {
+ for (Node child = node.getFirstChild(); child != null;
+ child = child.getNextSibling()) {
+ if (child.getNodeType() == Node.ELEMENT_NODE
+ && JMManagerFactoryImpl.NAMESPACE_URI.equals(
+ child.getNamespaceURI())) {
+ if (DBURL_NODE_NAME.equals(child.getLocalName())) {
+ String url = JMManagerFactoryImpl.getNodeText(child);
+ try {
+ dbURL = new URL(url);
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException(
+ "Invalid database URL: " + url);
+ }
+ } else if (
+ USER_NODE_NAME.equals(child.getLocalName())) {
+ user = JMManagerFactoryImpl.getNodeText(child);
+ } else if (
+ PASSWORD_NODE_NAME.equals(child.getLocalName())) {
+ password = JMManagerFactoryImpl.getNodeText(child);
+ } else if (
+ ID_ATTRIBUTE.equals(child.getLocalName())) {
+ idAttribute = JMManagerFactoryImpl.getNodeText(child);
+ } else if (
+ ID_ATTRIBUTE_NS.equals(child.getLocalName())) {
+ idAttributeNS = JMManagerFactoryImpl.getNodeText(child);
+ } else if (
+ TARGETNAMESPACE_IN.equals(child.getLocalName())) {
+ targetNamespaceIn = JMManagerFactoryImpl.getNodeText(child);
+ } else if (USE_CURSORING.equals(child.getLocalName())) {
+ String uc = JMManagerFactoryImpl.getNodeText(child);
+ useCursoring = (uc != null && "yes".equals(uc));
+ }
+ }
+ }
+ if (idAttribute != null && idAttributeNS == null)
+ idAttributeNS = "";
}
- } else if (USER_NODE_NAME.equals(child.getLocalName())) {
- user = JMManagerFactoryImpl.getNodeText(child);
- } else if (PASSWORD_NODE_NAME.equals(child.getLocalName())) {
- password = JMManagerFactoryImpl.getNodeText(child);
- } else if (ID_ATTRIBUTE.equals(child.getLocalName())) {
- idAttribute = JMManagerFactoryImpl.getNodeText(child);
- } else if (ID_ATTRIBUTE_NS.equals(child.getLocalName())) {
- idAttributeNS = JMManagerFactoryImpl.getNodeText(child);
- } else if (TARGETNAMESPACE_IN.equals(child.getLocalName())) {
- targetNamespaceIn = JMManagerFactoryImpl.getNodeText(child);
- }
}
- }
- if(idAttribute != null && idAttributeNS == null)
- idAttributeNS = "";
}
- }
}
- }
- /** Creates a new instance of InoManager */
- public InoManagerNoNs() {
- spf = SAXParserFactory.newInstance();
- spf.setNamespaceAware(true);
- spf.setValidating(false);
- }
+ /** Creates a new instance of InoManager */
+ public InoManagerNoNs() {
+ spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ spf.setValidating(false);
+ }
- /** <p>Deletes the given document from the database.</p>
- */
- public void delete(JMAnyElement pElement) throws SAXException {
- String query = getDeleteQuery(pElement);
- performQuery(query, (List) null);
- }
+ /** <p>Deletes the given document from the database.</p>
+ */
+ public void delete(JMAnyElement pElement) throws SAXException {
+ String query = getDeleteQuery(pElement);
+ performQuery(query, (List) null);
+ }
- /** <p>Inserts the given document into the database.</p>
- */
- public void insert(JMAnyElement pElement) throws SAXException {
- String query = getInsertQuery(pElement);
- List idList = new ArrayList();
- InoResponseHandlerNoNs irh = performQuery(query, idList);
- if (idList.size() == 0) {
- throw new SAXException("Query did not return an ino:id");
+ /** <p>Inserts the given document into the database.</p>
+ */
+ public void insert(JMAnyElement pElement) throws SAXException {
+ String query = getInsertQuery(pElement);
+ List idList = new ArrayList();
+ InoResponseHandlerNoNs irh = performQuery(query, idList);
+ if (idList.size() == 0) {
+ throw new SAXException("Query did not return an ino:id");
+ }
+ setElementId(pElement, (String) idList.get(0));
}
- setElementId(pElement, (String) idList.get(0));
- }
- /** <p>Updates the given document in the database.</p>
- */
- public void update(JMAnyElement pElement) throws SAXException {
- String query = getUpdateQuery(pElement);
- performQuery(query, (List) null);
- }
+ /** <p>Updates the given document in the database.</p>
+ */
+ public void update(JMAnyElement pElement) throws SAXException {
+ String query = getUpdateQuery(pElement);
+ performQuery(query, (List) null);
+ }
- /** <p>Defines the given schema in the database.</p>
- */
- public void define(String pSchema) throws SAXException {
- String query = "_define=" + URLEncoder.encode(pSchema);
- performQuery(query, (java.util.List) null);
- }
+ /** <p>Defines the given schema in the database.</p>
+ */
+ public void define(String pSchema) throws SAXException {
+ String query = "_define=" + URLEncoder.encode(pSchema);
+ performQuery(query, (List) null);
+ }
- /** <p>Performs a single database query.</p>
- */
- protected HttpURLConnection getResponse(String pQuery) throws SAXException {
- URL connectionURL = dbURL;
- try {
- if (useGet) {
- String dburl = connectionURL.toString();
- String url;
- if (dburl.indexOf('?') > 0) {
- url = dburl + "&" + pQuery;
- } else {
- url = dburl + "?" + pQuery;
- }
- try {
- connectionURL = new URL(url);
- HttpURLConnection conn = (HttpURLConnection) connectionURL.openConnection();
- conn.setDoOutput(false);
- conn.setDoInput(true);
- return conn;
- } catch (MalformedURLException e) {
- throw new SAXException("Malformed database URL: " + url);
- }
- } else {
- HttpURLConnection conn = (HttpURLConnection) connectionURL.openConnection();
- conn.setDoOutput(true);
- conn.setDoInput(true);
+ /** <p>Reads documents matching the given query. For any document
+ * matching, the Observer's notify method is executed with the
+ * matching document as an argument.</p>
+ * <p>The query may contain placeholders. If it does, you have
+ * to supply an object array with two elements per placeholder:
+ * An Integer with a java.sql.Types type and the actual placeholder
+ * value. Example:
+ * <pre>
+ * manager.select("Name = ? and Id = ?",
+ * new Object[]{JMManager.VARCHAR,
+ * "Someone",
+ * JMManager.INTEGER,
+ * 4}, 0, 0);
+ * </pre></p>
+ *
+ * @param pObserver This Observer is notified for any matching document.
+ * The document is added as an argument.
+ * @param pQuery The query to perform. May contain placeholders.
+ * @param pPlaceHolderArgs An array of objects or null, if the
+ * query doesn't contain any placeholders.
+ * @param pStart Ignore the given number of result documents at the
+ * beginning. A value of zero will return all documents.
+ * @param pMax Return at most the given number of documents. A value
+ * of zero will return all documents.
+ */
+ public void select(Observer pObserver, String pQuery, Object[] pPlaceHolderArgs,
+ int pStart, int pMax) throws SAXException {
+ select(pObserver, pQuery, pPlaceHolderArgs, pStart, pMax, (ResultInfo) null);
+ }
- OutputStream ostream = conn.getOutputStream();
- Writer w = new OutputStreamWriter(ostream);
- w.write(pQuery);
- w.close();
- return conn;
- }
- } catch (IOException e) {
- throw new SAXException("I/O Error: " + e.getMessage(), e);
+ /* (non-Javadoc)
+ * @see de.ispsoft.jaxme.JMManager#select(java.lang.String, java.lang.Object[], int, int, de.ispsoft.jaxme.ResultInfo)
+ */
+ public Iterator select(String pQuery, Object[] pPlaceHolderArgs, int pStart,
+ int pMax, ResultInfo pResultInfo) throws SAXException {
+ MyObserver o = new MyObserver();
+ select(o, pQuery, pPlaceHolderArgs, pStart, pMax, pResultInfo);
+ return o.resultList.iterator();
}
- }
- /** <p>Performs a single database query.</p>
- */
- protected InoResponseHandlerNoNs performQuery(String pQuery, java.util.List pList)
- throws SAXException {
- InoResponseHandlerNoNs irh = new InoResponseHandlerNoNs();
- if (pList != null) {
- irh.setInoObjectIdList(pList);
+ /* (non-Javadoc)
+ * @see de.ispsoft.jaxme.JMManager#select(de.ispsoft.jaxme.Observer, java.lang.String, java.lang.Object[], int, int, de.ispsoft.jaxme.ResultInfo)
+ */
+ public void select(Observer pObserver, String pQuery, Object[] pPlaceHolderArgs,
+ int pStart, int pMax, ResultInfo pResultInfo) throws SAXException {
+ if (pPlaceHolderArgs != null && pPlaceHolderArgs.length > 0) {
+ throw new SAXException("Placeholders are not yet supported");
+ }
+ String q;
+ if (useCursoring) {
+ if(pStart == 0 && pMax == 0) {
+ q = "_xql(1,0)=" + URLEncoder.encode(pQuery);
+ } else {
+ q = "_cursor=open&_count=cheap&_xql=" + URLEncoder.encode(pQuery);
+ if (pStart != 0 || pMax != 0) {
+ q += "&_position=" + (pStart + 1) + "&_quantity=" + pMax;
+ }
+ }
+ } else {
+ if (pStart != 0 || pMax != 0) {
+ q = "_xql(" + (pStart + 1) + "," + pMax + ")=";
+ } else {
+ q = "_xql=";
+ }
+ q += URLEncoder.encode(pQuery);
+ }
+ InoResponseHandlerNoNs irh = new InoResponseHandlerNoNs();
+ irh.setResultInfo(pResultInfo);
+ JMContentHandler ch = getJMContentHandler();
+ ch.setObserver(pObserver);
+ irh.setResultHandler(ch);
+ performQuery(q, irh);
}
- performQuery(pQuery, irh);
- return irh;
- }
- /** <p>Parses a single INO response document.</p>
- */
- protected void performQuery(String pQuery, InoResponseHandlerNoNs pHandler)
- throws SAXException {
- if(idAttribute != null)
- pHandler.setAttributeMappingId(idAttribute, idAttributeNS);
- if(targetNamespaceIn != null)
- pHandler.setTargetNamespace(targetNamespaceIn);
- HttpURLConnection conn = getResponse(pQuery);
- try {
- InputSource isource = new InputSource(conn.getInputStream());
- isource.setEncoding(conn.getContentEncoding());
- XMLReader xr;
- SAXParser sp = spf.newSAXParser();
- xr = sp.getXMLReader();
- xr.setContentHandler(pHandler);
- xr.parse(isource);
- } catch (ParserConfigurationException e) {
- throw new SAXException("ParserConfigurationException: " + e.getMessage(), e);
- } catch (IOException e) {
- throw new SAXException("I/O Exception: " + e.getMessage(), e);
+ /** <p>Returns the element ID. The default implementation
+ * returns
+ * <code>getAttribute(InoResponseHandler.INO_RESPONSE2_URI, "id")</code>.
+ * If you use another element as the ID, change this.</p>
+ */
+ protected String getElementId(JMAnyElement pElement) throws SAXException {
+ if (idAttribute != null) {
+ String id = pElement.getAttribute(idAttributeNS, idAttribute, null);
+ pElement.removeAttribute(idAttributeNS, idAttribute);
+ return id;
+ } else
+ return pElement.getAttribute(InoResponseHandlerNoNs.INO_RESPONSE2_URI,
+ "id", null);
}
- }
- /** <p>Reads documents matching the given query. For any document
- * matching, the Observer's notify method is executed with the
- * matching document as an argument.</p>
- * <p>The query may contain placeholders. If it does, you have
- * to supply an object array with two elements per placeholder:
- * An Integer with a java.sql.Types type and the actual placeholder
- * value. Example:
- * <pre>
- * manager.select("Name = ? and Id = ?",
- * new Object[]{JMManager.VARCHAR,
- * "Someone",
- * JMManager.INTEGER,
- * 4}, 0, 0);
- * </pre></p>
- *
- * @param pObserver This Observer is notified for any matching document.
- * The document is added as an argument.
- * @param pQuery The query to perform. May contain placeholders.
- * @param pPlaceHolderArgs An array of objects or null, if the
- * query doesn't contain any placeholders.
- * @param pStart Ignore the given number of result documents at the
- * beginning. A value of zero will return all documents.
- * @param pMax Return at most the given number of documents. A value
- * of zero will return all documents.
- */
- public void select(Observer pObserver, String pQuery, Object[] pPlaceHolderArgs, int pStart, int pMax) throws SAXException {
- if (pPlaceHolderArgs != null && pPlaceHolderArgs.length > 0) {
- throw new SAXException("Placeholders are not yet supported");
+ /** <p>After an insert, sets the elements ID. The default
+ * implementation performs
+ * <code>setAttribute(InoResponseHandler.INO_RESPONSE2_URI, "id", pId)</code>.
+ * If you use another element as the ID, change this. You probably need
+ * to read the inserted document by using the supplied ino:id.</p>
+ */
+ protected void setElementId(JMAnyElement pElement, String pId) throws SAXException {
+ pElement.setAttribute(InoResponseHandlerNoNs.INO_RESPONSE2_URI, "id",
+ pId, null);
+ if (idAttribute != null) {
+ pElement.setAttribute(idAttributeNS, idAttribute, pId, null);
+ }
}
- String q;
- if (pStart != 0 || pMax != 0) {
- q = "_xql(" + (pStart+1) + "," + pMax + ")=";
- } else {
- q = "_xql=";
+
+ /** <p>Returns a query suited for deleting the element.</p>
+ */
+ protected String getDeleteQuery(JMAnyElement pElement) throws SAXException {
+ String id = getElementId(pElement);
+ if (id == null || id.length() == 0) {
+ throw new SAXException("The element being deleted doesn't have an ID.");
+ }
+ return "_delete=" + URLEncoder.encode(pElement.getLocalName() + "[@ino:id=" + id + "]");
}
- q += URLEncoder.encode(pQuery);
- InoResponseHandlerNoNs irh = new InoResponseHandlerNoNs();
- JMContentHandler ch = getJMContentHandler();
- ch.setObserver(pObserver);
- irh.setResultHandler(ch);
- performQuery(q, irh);
- }
-
- /**
- * @return
+ /** <p>Returns a query suited for updating the element.</p>
*/
- public URL getDbURL() {
- return dbURL;
+ protected String getUpdateQuery(JMAnyElement pElement) throws SAXException {
+ String id = getElementId(pElement);
+ if (id == null || id.length() == 0) {
+ throw new SAXException("The element being updated doesn't have an ID.");
+ }
+ return "_process=" + URLEncoder.encode(pElement.toXMLNoNS());
}
-
- /**
- * @param url
+
+ /** <p>Returns a query suited for inserting the element.</p>
*/
- public void setDbURL(URL url) {
- dbURL = url;
+ protected String getInsertQuery(JMAnyElement pElement) throws SAXException {
+ String id = getElementId(pElement);
+ if (id != null && id.length() > 0) {
+ throw new SAXException("The element being inserted already has an ID.");
+ }
+ return "_process=" + URLEncoder.encode(pElement.toXMLNoNS());
+ }
+
+ /** <p>Performs a single database query.</p>
+ */
+ protected HttpURLConnection getResponse(String pQuery) throws SAXException {
+ URL connectionURL = dbURL;
+ try {
+ if (useGet) {
+ String dburl = connectionURL.toString();
+ String url;
+ if (dburl.indexOf('?') > 0) {
+ url = dburl + "&" + pQuery;
+ } else {
+ url = dburl + "?" + pQuery;
+ }
+ try {
+ connectionURL = new URL(url);
+ HttpURLConnection conn = (HttpURLConnection) connectionURL.openConnection();
+ conn.setDoOutput(false);
+ conn.setDoInput(true);
+ return conn;
+ } catch (MalformedURLException e) {
+ throw new SAXException("Malformed database URL: " + url);
+ }
+ } else {
+ HttpURLConnection conn = (HttpURLConnection) connectionURL.openConnection();
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ OutputStream ostream = conn.getOutputStream();
+ Writer w = new OutputStreamWriter(ostream);
+ w.write(pQuery);
+ w.close();
+ return conn;
+ }
+ } catch (IOException e) {
+ throw new SAXException("I/O Error: " + e.getMessage(), e);
+ }
+ }
+
+ /** <p>Performs a single database query.</p>
+ */
+ protected InoResponseHandlerNoNs performQuery(String pQuery, List pList)
+ throws SAXException {
+ InoResponseHandlerNoNs irh = new InoResponseHandlerNoNs();
+ if (pList != null) {
+ irh.setInoObjectIdList(pList);
+ }
+ performQuery(pQuery, irh);
+ return irh;
+ }
+
+ /** <p>Parses a single INO response document.</p>
+ */
+ protected void performQuery(String pQuery, InoResponseHandlerNoNs pHandler)
+ throws SAXException {
+ if (idAttribute != null)
+ pHandler.setAttributeMappingId(idAttribute, idAttributeNS);
+ if (targetNamespaceIn != null)
+ pHandler.setTargetNamespace(targetNamespaceIn);
+ HttpURLConnection conn = getResponse(pQuery);
+ try {
+ InputSource isource = new InputSource(conn.getInputStream());
+ isource.setEncoding(conn.getContentEncoding());
+ XMLReader xr;
+ SAXParser sp = spf.newSAXParser();
+ xr = sp.getXMLReader();
+ xr.setContentHandler(pHandler);
+ xr.parse(isource);
+ } catch (ParserConfigurationException e) {
+ throw new SAXException(
+ "ParserConfigurationException: " + e.getMessage(),
+ e);
+ } catch (IOException e) {
+ throw new SAXException("I/O Exception: " + e.getMessage(), e);
+ }
}
}
|