Is there anyway to get a more elaborate error message for an xforms-
submit-error event? I find that I spend a lot of time feeling in the dark for simple mistakes I make which prevent the form from saving. Although I capture the event successfully, I'm often at a loss about the cause of the error. Duane -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Duane,
This is an excellent question. From the XForms spec's point of view, if submission fails, an xforms-submit-error event is thrown and that's it, which is not extremely helpful. Some tips: 1. If you are using XML schema for instance validation and suspect that validation may be failing because validation doesn't pass, try using an online schema validator with your submitted XForms instance. 2. You can enable server-side logging for XForms with: <category name="org.orbeon.oxf.xforms.processor.XFormsServer"> <priority value="debug"/> </category> in log4j.xml, the XForms instance that failed to be saved will be logged with some annotations. This can help a little bit, but I agree that this is not enough. We have an RFE for a client-side XForms console, which would be the right place to provide useful information about submission: http://forge.objectweb.org/tracker/index.php?func=detail&aid=304142&group_id=168&atid=350210 This will be post-3.0 however. -Erik Duane Gran wrote: > Is there anyway to get a more elaborate error message for an xforms- > submit-error event? I find that I spend a lot of time feeling in the > dark for simple mistakes I make which prevent the form from saving. > Although I capture the event successfully, I'm often at a loss about > the cause of the error. > > Duane -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
I need to play with the SQLProcessor and its whole environment. But it is a little bit hard to understand. Could someone give me some hints about the architecture (used patterns, some class diagramm drawings). My concrete task is to make procedure calls where (in)out parameters are supported. That does not mean that I need the parameters as ops output. I just need to call procedures where (in)-out parameters are used. Are there special reasons, that the procedure call support only in parameters (technical problems? time?)? If the task is not to heavy I could try the extension. Sebastian -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Sebastian Kraus/INPLUS/DE wrote:
> > I need to play with the SQLProcessor and its whole environment. > But it is a little bit hard to understand. > Could someone give me some hints about the architecture (used patterns, > some class diagramm drawings). Unfortunately, we don't have such internal documentation at this point. You are right that this is not trivial to understand ;-) A first round of refactoring was performed on the SQL processor when support for stored procedures was sponsored not long ago. A second round is clearly needed, in particular the SQL processor's interpreter should use some new support classes (which the XForms engine already uses). This would make the code easier to understand. > My concrete task is to make procedure calls where (in)out parameters > are supported. That does not mean that I need the parameters as ops > output. I just need to call procedures where (in)-out parameters > are used. > > Are there special reasons, that the procedure call support only in > parameters (technical problems? time?)? Time, and the fact that nobody asked for it. > If the task is not to heavy I could try the extension. Of course, please go ahead! Don't forget that you can also sponsor the feature. Rates are quite reasonable ;-) -Erik -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Hi Erik, I needed a quick solution und could fix the biggest problems by cheating on the DB level. But nevertheless I will need a good working procedure call processor in the future. So I will mention this issue when I go into the next round. thx Sebastian
Sebastian Kraus/INPLUS/DE wrote: > > I need to play with the SQLProcessor and its whole environment. > But it is a little bit hard to understand. > Could someone give me some hints about the architecture (used patterns, > some class diagramm drawings). Unfortunately, we don't have such internal documentation at this point. You are right that this is not trivial to understand ;-) A first round of refactoring was performed on the SQL processor when support for stored procedures was sponsored not long ago. A second round is clearly needed, in particular the SQL processor's interpreter should use some new support classes (which the XForms engine already uses). This would make the code easier to understand. > My concrete task is to make procedure calls where (in)out parameters > are supported. That does not mean that I need the parameters as ops > output. I just need to call procedures where (in)-out parameters > are used. > > Are there special reasons, that the procedure call support only in > parameters (technical problems? time?)? Time, and the fact that nobody asked for it. > If the task is not to heavy I could try the extension. Of course, please go ahead! Don't forget that you can also sponsor the feature. Rates are quite reasonable ;-) -Erik -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
In reply to this post by Erik Bruchez
Happy new Year! I tried to store and retriev BLOG binary streams with ops without success. Here the Facts. 1. I'm using OPS version 2.8 used for our productive system. But in this post I will only talk about 3.0beta4 because the documentation refers to that version. 2. My oracle table is "test_blob" with two columns: TEXT_COL (varchar2) and BLOB_COL (BLOB) 3. I' using the jdbc driver classes12.jar 4. All INSERT and SELECT statements on the TEXT_COL work quite well 5. Going with the documentation I tried the following a) reading a jpg from the filesystem. Using the http-serializer, I can see it in my browser. The debug statement shows mea good looking xml like <document xsi:type="xs:base64Binary" content-type="image/jpeg"> /9j/4AAQSkZJRgABAQEBygHKAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4R </document> b) When trying the insert I get a nullpointer exception after the sql processor tag. The last class on the stacke trace is org.orbeon.oxf.processor.sql.interpreters.ValueOfCopyOfInterpreter. c) What I'm doing wrong??? :-( <?xml version="1.0" encoding="utf-8"?> <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <p:processor name="oxf:url-generator"> <p:input name="config"> <config> <url>file:///C:/gtamap.jpg</url> <content-type>image/jpeg</content-type> </config> </p:input> <p:output name="data" id="image-data" debug="mypictur"/> </p:processor> <p:processor name="oxf:sql" xmlns:sql="http://orbeon.org/oxf/xml/sql"> <p:input name="data" href="#image-data"/> <p:input name="config"> <sql:config> <result> <sql:connection> <sql:datasource>mydb</sql:datasource> <sql:execute> <sql:update> <!-- HERE IS the PROBLEM--> insert into TEST_BLOB(BLOB_COL) values ( <sql:param type="xs:base64Binary" select="/*"/>) <!-- the next line works quite well --> <!-- insert into TEST_BLOB (TEXT_COL) values ('Bart') --> </sql:update> </sql:execute> </sql:connection> </result> </sql:config> </p:input> </p:processor> </p:config> 6. I tried to use the anyUri Type insert into TEST_SK (TEST_BLOB) values ( <sql:param select="/*" type="xs:anyURI"/>) and used a identity proc <p:processor name="oxf:identity"> <p:input name="data"> <uri xsi:type="xs:string">file:///C:/gtamap.jpg</uri> </p:input> <p:output name="data" id="image-uri" debug="i-uri"/> </p:processor> both types were used. xs:string and xs:base64Binary I sent the output to the http-serializer too. When using xs:string i got an error like "Die Grafik "http://localhost:8080/myops/filetest2" kann nicht angezeigt werden, weil sie Fehler enthält." That means the image is corrupted. When using xs:base64Binary, I have the nullpointer exception again -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
I have to say sorry for that long post without reading the documentation exactly :-( Before I used Tomcat 5.5. With 4.1 it works. And I had en error in the xpl. It should be insert into TEST_BLOB(BLOB_COL) values ( <sql:param type="xs:base64Binary" select="document"/>) instead of /* On 5.5 I got now an error java.lang.NoClassDefFoundError: org/apache/commons/dbcp/DelegatingPreparedStatement org.orbeon.oxf.processor.sql.delegates.SQLProcessorOracleTomcatDelegate.getOraclePreparedStatement(SQLProcessorOracleTomcatDelegate.java:36) org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.getBlobOutputStream(SQLProcessorOracleDelegateBase.java:95) org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.setBlob(SQLProcessorOracleDelegateBase.java:83) But now there is a new question. How can I do the same with Tomcat 5.5. I think the answer is in the file SQLProcessorOracleTomcatDelegate.java But I do not know the jdbc api or tomcat api's quite well. Could someone give me some hints? thx Sebastian
Happy new Year! I tried to store and retriev BLOG binary streams with ops without success. Here the Facts. 1. I'm using OPS version 2.8 used for our productive system. But in this post I will only talk about 3.0beta4 because the documentation refers to that version. 2. My oracle table is "test_blob" with two columns: TEXT_COL (varchar2) and BLOB_COL (BLOB) 3. I' using the jdbc driver classes12.jar 4. All INSERT and SELECT statements on the TEXT_COL work quite well 5. Going with the documentation I tried the following a) reading a jpg from the filesystem. Using the http-serializer, I can see it in my browser. The debug statement shows mea good looking xml like <document xsi:type="xs:base64Binary" content-type="image/jpeg"> /9j/4AAQSkZJRgABAQEBygHKAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4R </document> b) When trying the insert I get a nullpointer exception after the sql processor tag. The last class on the stacke trace is org.orbeon.oxf.processor.sql.interpreters.ValueOfCopyOfInterpreter. c) What I'm doing wrong??? :-( <?xml version="1.0" encoding="utf-8"?> <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <p:processor name="oxf:url-generator"> <p:input name="config"> <config> <url>file:///C:/gtamap.jpg</url> <content-type>image/jpeg</content-type> </config> </p:input> <p:output name="data" id="image-data" debug="mypictur"/> </p:processor> <p:processor name="oxf:sql" xmlns:sql="http://orbeon.org/oxf/xml/sql"> <p:input name="data" href="#image-data"/> <p:input name="config"> <sql:config> <result> <sql:connection> <sql:datasource>mydb</sql:datasource> <sql:execute> <sql:update> <!-- HERE IS the PROBLEM--> insert into TEST_BLOB(BLOB_COL) values ( <sql:param type="xs:base64Binary" select="/*"/>) <!-- the next line works quite well --> <!-- insert into TEST_BLOB (TEXT_COL) values ('Bart') --> </sql:update> </sql:execute> </sql:connection> </result> </sql:config> </p:input> </p:processor> </p:config> 6. I tried to use the anyUri Type insert into TEST_SK (TEST_BLOB) values ( <sql:param select="/*" type="xs:anyURI"/>) and used a identity proc <p:processor name="oxf:identity"> <p:input name="data"> <uri xsi:type="xs:string">file:///C:/gtamap.jpg</uri> </p:input> <p:output name="data" id="image-uri" debug="i-uri"/> </p:processor> both types were used. xs:string and xs:base64Binary I sent the output to the http-serializer too. When using xs:string i got an error like "Die Grafik "http://localhost:8080/myops/filetest2" kann nicht angezeigt werden, weil sie Fehler enthält." That means the image is corrupted. When using xs:base64Binary, I have the nullpointer exception again -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Hi there, as mentioned below, I need to work with BLOG's on Oracle 9 or 10, Tomcat 5.5 and OPS 2.8. The current SQL Processor implementation only supports blob handling on Tomcat 4.1 Here is the solution for Tomcat 5.5 and OPS 2.8 (3.0 should be similary) a) Get the sourcecode of an OPS version 2.8. Make sure you are able to compile the java source code b) Add the naming-factory-dbcp.jar library which can be found in the <tomact_home>/common/lib folder to your classpath. This library seems to be the successor of commons-dbcp-1.1.jar. c) Open SQLProcessorOracleTomcatDelegate.java in the package org.orbeon.oxf.processor.sql and replace the to lines import org.apache.commons.dbcp.DelegatingPreparedStatement; import org.apache.commons.dbcp.DelegatingResultSet; with import org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement; import org.apache.tomcat.dbcp.dbcp.DelegatingResultSet; d) Compile and make a new ops.jar Hope this helps somebody else Sebastian
I have to say sorry for that long post without reading the documentation exactly :-( Before I used Tomcat 5.5. With 4.1 it works. And I had en error in the xpl. It should be insert into TEST_BLOB(BLOB_COL) values ( <sql:param type="xs:base64Binary" select="document"/>) instead of /* On 5.5 I got now an error java.lang.NoClassDefFoundError: org/apache/commons/dbcp/DelegatingPreparedStatement org.orbeon.oxf.processor.sql.delegates.SQLProcessorOracleTomcatDelegate.getOraclePreparedStatement(SQLProcessorOracleTomcatDelegate.java:36) org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.getBlobOutputStream(SQLProcessorOracleDelegateBase.java:95) org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.setBlob(SQLProcessorOracleDelegateBase.java:83) But now there is a new question. How can I do the same with Tomcat 5.5. I think the answer is in the file SQLProcessorOracleTomcatDelegate.java But I do not know the jdbc api or tomcat api's quite well. Could someone give me some hints? thx Sebastian
Happy new Year! I tried to store and retriev BLOG binary streams with ops without success. Here the Facts. 1. I'm using OPS version 2.8 used for our productive system. But in this post I will only talk about 3.0beta4 because the documentation refers to that version. 2. My oracle table is "test_blob" with two columns: TEXT_COL (varchar2) and BLOB_COL (BLOB) 3. I' using the jdbc driver classes12.jar 4. All INSERT and SELECT statements on the TEXT_COL work quite well 5. Going with the documentation I tried the following a) reading a jpg from the filesystem. Using the http-serializer, I can see it in my browser. The debug statement shows mea good looking xml like <document xsi:type="xs:base64Binary" content-type="image/jpeg"> /9j/4AAQSkZJRgABAQEBygHKAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4R </document> b) When trying the insert I get a nullpointer exception after the sql processor tag. The last class on the stacke trace is org.orbeon.oxf.processor.sql.interpreters.ValueOfCopyOfInterpreter. c) What I'm doing wrong??? :-( <?xml version="1.0" encoding="utf-8"?> <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:oxf="http://www.orbeon.com/oxf/processors" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <p:processor name="oxf:url-generator"> <p:input name="config"> <config> <url>file:///C:/gtamap.jpg</url> <content-type>image/jpeg</content-type> </config> </p:input> <p:output name="data" id="image-data" debug="mypictur"/> </p:processor> <p:processor name="oxf:sql" xmlns:sql="http://orbeon.org/oxf/xml/sql"> <p:input name="data" href="#image-data"/> <p:input name="config"> <sql:config> <result> <sql:connection> <sql:datasource>mydb</sql:datasource> <sql:execute> <sql:update> <!-- HERE IS the PROBLEM--> insert into TEST_BLOB(BLOB_COL) values ( <sql:param type="xs:base64Binary" select="/*"/>) <!-- the next line works quite well --> <!-- insert into TEST_BLOB (TEXT_COL) values ('Bart') --> </sql:update> </sql:execute> </sql:connection> </result> </sql:config> </p:input> </p:processor> </p:config> 6. I tried to use the anyUri Type insert into TEST_SK (TEST_BLOB) values ( <sql:param select="/*" type="xs:anyURI"/>) and used a identity proc <p:processor name="oxf:identity"> <p:input name="data"> <uri xsi:type="xs:string">file:///C:/gtamap.jpg</uri> </p:input> <p:output name="data" id="image-uri" debug="i-uri"/> </p:processor> both types were used. xs:string and xs:base64Binary I sent the output to the http-serializer too. When using xs:string i got an error like "Die Grafik "http://localhost:8080/myops/filetest2" kann nicht angezeigt werden, weil sie Fehler enthält." That means the image is corrupted. When using xs:base64Binary, I have the nullpointer exception again -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Sebastian,
Thanks for looking into this! -Erik Sebastian Kraus/INPLUS/DE wrote: > > Hi there, > > as mentioned below, I need to work with BLOG's on Oracle 9 or 10, Tomcat > 5.5 and OPS 2.8. > The current SQL Processor implementation only supports blob handling on > Tomcat 4.1 > > Here is the solution for Tomcat 5.5 and OPS 2.8 (3.0 should be similary) > > a) Get the sourcecode of an OPS version 2.8. Make sure you are able to > compile the java source code > b) Add the naming-factory-dbcp.jar library which can be found in the > <tomact_home>/common/lib folder to your classpath. This library seems to > be the successor of commons-dbcp-1.1.jar. > c) Open SQLProcessorOracleTomcatDelegate.java in the package > org.orbeon.oxf.processor.sql and replace the to lines > import org.apache.commons.dbcp.DelegatingPreparedStatement; > import org.apache.commons.dbcp.DelegatingResultSet; > with > import org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement; > import org.apache.tomcat.dbcp.dbcp.DelegatingResultSet; > d) Compile and make a new ops.jar > > Hope this helps somebody else > > Sebastian > > > > > > *"Sebastian Kraus/INPLUS/DE" <[hidden email]>* > > 05.01.2006 18:47 > Please respond to > [hidden email] > > > > To > [hidden email] > cc > > Subject > Re: [ops-users] Storing and retrieving BLOG from Oracle > > > > > > > > > > I have to say sorry for that long post without reading the documentation > exactly :-( > Before I used Tomcat 5.5. With 4.1 it works. > And I had en error in the xpl. It should be > insert into TEST_BLOB(BLOB_COL) values ( <sql:param > type="xs:base64Binary" select="document"/>) > instead of /* > > On 5.5 I got now an error > > java.lang.NoClassDefFoundError: > org/apache/commons/dbcp/DelegatingPreparedStatement > > org.orbeon.oxf.processor.sql.delegates.SQLProcessorOracleTomcatDelegate.getOraclePreparedStatement(SQLProcessorOracleTomcatDelegate.java:36) > > > org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.getBlobOutputStream(SQLProcessorOracleDelegateBase.java:95) > > > org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.setBlob(SQLProcessorOracleDelegateBase.java:83) > > > > But now there is a new question. How can I do the same with Tomcat 5.5. > I think the answer is in the file SQLProcessorOracleTomcatDelegate.java > But I do not know the jdbc api or tomcat api's quite well. > Could someone give me some hints? > > thx > > Sebastian > > > > > > *"Sebastian Kraus/INPLUS/DE" <[hidden email]>* > > 04.01.2006 19:19 > Please respond to > [hidden email] > > > To > [hidden email] > cc > > Subject > [ops-users] Storing and retrieving BLOG from Oracle > > > > > > > > > > > > Happy new Year! > > I tried to store and retriev BLOG binary streams with ops without success. > > Here the Facts. > > 1. I'm using OPS version 2.8 used for our productive system. But in this > post I will only talk about 3.0beta4 because the documentation refers to > that version. > > 2. My oracle table is "test_blob" with two columns: TEXT_COL (varchar2) > and BLOB_COL (BLOB) > > 3. I' using the jdbc driver classes12.jar > > 4. All INSERT and SELECT statements on the TEXT_COL work quite well > > 5. Going with the documentation I tried the following > > a) reading a jpg from the filesystem. Using the http-serializer, I > can see it in my browser. The debug statement shows mea good looking xml > like > <document xsi:type="xs:base64Binary" > content-type="image/jpeg"> > > /9j/4AAQSkZJRgABAQEBygHKAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4R > </document> > b) When trying the insert I get a nullpointer exception after the > sql processor tag. The last class on the stacke trace is > org.orbeon.oxf.processor.sql.interpreters.ValueOfCopyOfInterpreter. > > c) What I'm doing wrong??? :-( > > > > <?xml version="1.0" encoding="utf-8"?> > > <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" > xmlns:oxf="http://www.orbeon.com/oxf/processors" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xmlns:xs="http://www.w3.org/2001/XMLSchema"> > > > <p:processor name="oxf:url-generator"> > <p:input name="config"> > <config> > <url>file:///C:/gtamap.jpg</url> > <content-type>image/jpeg</content-type> > </config> > </p:input> > <p:output name="data" id="image-data" debug="mypictur"/> > </p:processor> > > > <p:processor name="oxf:sql" xmlns:sql="http://orbeon.org/oxf/xml/sql"> > <p:input name="data" href="#image-data"/> > <p:input name="config"> > <sql:config> > <result> > <sql:connection> > <sql:datasource>mydb</sql:datasource> > <sql:execute> > <sql:update> > <!-- HERE IS the PROBLEM--> > insert into TEST_BLOB(BLOB_COL) values ( > <sql:param type="xs:base64Binary" select="/*"/>) > <!-- the next line works quite well --> > <!-- insert into TEST_BLOB (TEXT_COL) values > ('Bart') --> > </sql:update> > </sql:execute> > </sql:connection> > </result> > </sql:config> > </p:input> > </p:processor> > </p:config> > > > 6. I tried to use the anyUri Type > insert into TEST_SK (TEST_BLOB) values ( <sql:param > select="/*" type="xs:anyURI"/>) > and used a identity proc > > <p:processor name="oxf:identity"> > <p:input name="data"> > <uri xsi:type="xs:string">file:///C:/gtamap.jpg</uri> > </p:input> > <p:output name="data" id="image-uri" debug="i-uri"/> > </p:processor> > > both types were used. xs:string and xs:base64Binary > > I sent the output to the http-serializer too. When using xs:string i got > an error like "Die Grafik "http://localhost:8080/myops/filetest2" kann > nicht angezeigt werden, weil sie Fehler enthält." That means the image > is corrupted. > When using xs:base64Binary, I have the nullpointer exception again -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
I just added a bug to track this:
http://forge.objectweb.org/tracker/index.php?func=detail&aid=304463&group_id=168&atid=350207 -Erik Erik Bruchez wrote: > Sebastian, > > Thanks for looking into this! > > -Erik > > Sebastian Kraus/INPLUS/DE wrote: > >> >> Hi there, >> >> as mentioned below, I need to work with BLOG's on Oracle 9 or 10, >> Tomcat 5.5 and OPS 2.8. >> The current SQL Processor implementation only supports blob handling >> on Tomcat 4.1 >> >> Here is the solution for Tomcat 5.5 and OPS 2.8 (3.0 should be similary) >> >> a) Get the sourcecode of an OPS version 2.8. Make sure you are able >> to compile the java source code >> b) Add the naming-factory-dbcp.jar library which can be found in the >> <tomact_home>/common/lib folder to your classpath. This library seems >> to be the successor of commons-dbcp-1.1.jar. >> c) Open SQLProcessorOracleTomcatDelegate.java in the package >> org.orbeon.oxf.processor.sql and replace the to lines >> import org.apache.commons.dbcp.DelegatingPreparedStatement; >> import org.apache.commons.dbcp.DelegatingResultSet; >> with >> import org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement; >> import org.apache.tomcat.dbcp.dbcp.DelegatingResultSet; >> d) Compile and make a new ops.jar >> >> Hope this helps somebody else >> >> Sebastian >> >> >> >> >> >> *"Sebastian Kraus/INPLUS/DE" <[hidden email]>* >> >> 05.01.2006 18:47 >> Please respond to >> [hidden email] >> >> >> >> To >> [hidden email] >> cc >> >> Subject >> Re: [ops-users] Storing and retrieving BLOG from Oracle >> >> >> >> >> >> >> >> >> >> I have to say sorry for that long post without reading the >> documentation exactly :-( >> Before I used Tomcat 5.5. With 4.1 it works. >> And I had en error in the xpl. It should be >> insert into TEST_BLOB(BLOB_COL) values ( <sql:param >> type="xs:base64Binary" select="document"/>) instead of /* >> >> On 5.5 I got now an error >> >> java.lang.NoClassDefFoundError: >> org/apache/commons/dbcp/DelegatingPreparedStatement >> >> org.orbeon.oxf.processor.sql.delegates.SQLProcessorOracleTomcatDelegate.getOraclePreparedStatement(SQLProcessorOracleTomcatDelegate.java:36) >> >> >> org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.getBlobOutputStream(SQLProcessorOracleDelegateBase.java:95) >> >> >> org.orbeon.oxf.processor.sql.SQLProcessorOracleDelegateBase.setBlob(SQLProcessorOracleDelegateBase.java:83) >> >> >> >> But now there is a new question. How can I do the same with Tomcat 5.5. >> I think the answer is in the file SQLProcessorOracleTomcatDelegate.java >> But I do not know the jdbc api or tomcat api's quite well. >> Could someone give me some hints? >> >> thx >> >> Sebastian >> >> >> >> >> >> *"Sebastian Kraus/INPLUS/DE" <[hidden email]>* >> >> 04.01.2006 19:19 >> Please respond to >> [hidden email] >> >> >> To >> [hidden email] >> cc >> >> Subject >> [ops-users] Storing and retrieving BLOG from Oracle >> >> >> >> >> >> >> >> >> >> >> >> Happy new Year! >> >> I tried to store and retriev BLOG binary streams with ops without >> success. >> >> Here the Facts. >> >> 1. I'm using OPS version 2.8 used for our productive system. But in >> this post I will only talk about 3.0beta4 because the documentation >> refers to that version. >> >> 2. My oracle table is "test_blob" with two columns: TEXT_COL >> (varchar2) and BLOB_COL (BLOB) >> >> 3. I' using the jdbc driver classes12.jar >> >> 4. All INSERT and SELECT statements on the TEXT_COL work quite well >> >> 5. Going with the documentation I tried the following >> >> a) reading a jpg from the filesystem. Using the http-serializer, >> I can see it in my browser. The debug statement shows mea good looking >> xml like >> <document xsi:type="xs:base64Binary" >> content-type="image/jpeg"> >> >> /9j/4AAQSkZJRgABAQEBygHKAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4R >> </document> >> b) When trying the insert I get a nullpointer exception after >> the sql processor tag. The last class on the stacke trace is >> >> org.orbeon.oxf.processor.sql.interpreters.ValueOfCopyOfInterpreter. >> >> c) What I'm doing wrong??? :-( >> >> >> <?xml version="1.0" encoding="utf-8"?> >> >> <p:config xmlns:p="http://www.orbeon.com/oxf/pipeline" >> xmlns:oxf="http://www.orbeon.com/oxf/processors" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:xs="http://www.w3.org/2001/XMLSchema"> >> >> <p:processor name="oxf:url-generator"> <p:input >> name="config"> <config> >> <url>file:///C:/gtamap.jpg</url> >> <content-type>image/jpeg</content-type> </config> </p:input> >> <p:output name="data" id="image-data" debug="mypictur"/> >> </p:processor> >> >> >> <p:processor name="oxf:sql" >> xmlns:sql="http://orbeon.org/oxf/xml/sql"> <p:input name="data" >> href="#image-data"/> <p:input name="config"> >> <sql:config> >> <result> >> <sql:connection> >> <sql:datasource>mydb</sql:datasource> >> <sql:execute> >> <sql:update> >> <!-- HERE IS the PROBLEM--> >> insert into TEST_BLOB(BLOB_COL) values ( >> <sql:param type="xs:base64Binary" select="/*"/>) <!-- the next line >> works quite well --> >> <!-- insert into TEST_BLOB (TEXT_COL) >> values ('Bart') --> >> </sql:update> >> </sql:execute> >> </sql:connection> </result> >> </sql:config> </p:input> </p:processor> >> </p:config> >> >> >> 6. I tried to use the anyUri Type >> insert into TEST_SK (TEST_BLOB) values ( <sql:param >> select="/*" type="xs:anyURI"/>) and used a identity proc >> >> <p:processor name="oxf:identity"> >> <p:input name="data"> >> <uri xsi:type="xs:string">file:///C:/gtamap.jpg</uri> >> </p:input> >> <p:output name="data" id="image-uri" debug="i-uri"/> >> </p:processor> >> >> both types were used. xs:string and xs:base64Binary >> >> I sent the output to the http-serializer too. When using xs:string i >> got an error like "Die Grafik "http://localhost:8080/myops/filetest2" >> kann nicht angezeigt werden, weil sie Fehler enthält." That means the >> image is corrupted. >> When using xs:base64Binary, I have the nullpointer exception again > > -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
In reply to this post by Erik Bruchez
Option [2] (enabling debugging for
org.orbeon.oxf.xforms.processor.XFormsServer) is certainly helpful.
But it's pretty imprecise, because of the screeds of other debugging output which results from having this class set to debug (eg dumping of all instance documents). Sure this is all useful in it's own right, but it's a bit heavyweight just to find out you've misspelt a URL in your submission target. Certainly I couldn't turn this on by default in a production environment, whereas I do really need submission errors logged as standard in production. How about logging submission errors to a more specific logger (eg org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent)? This could then be reasonably enabled full-time. Personally I'd argue this logger be turned on by default because it's flat out impossible to determine the cause of an xforms-submit-error any other way. And there's nothing more frustrating - particularly for first time XForms authors - than watching absolutely nothing happen when you click on a 'Save' button: no errors displayed, no errors logged. Adrian Erik Bruchez wrote: Duane, -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
I should mention, if this sounds acceptable let me know and I can
submit the patch.
Adrian Baker wrote: Option [2] (enabling debugging for org.orbeon.oxf.xforms.processor.XFormsServer) is certainly helpful. -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
In reply to this post by Adrian Baker-2
Adrian,
I also think it is reasonable to have submission error logged by default, that is: in "info" priority. And as you say, we could log them with a separate logger, so one could disable those if needed. Erik what is your take on this? Alex On 2/27/06, Adrian Baker <[hidden email]> wrote: > Option [2] (enabling debugging for > org.orbeon.oxf.xforms.processor.XFormsServer) is certainly > helpful. > > But it's pretty imprecise, because of the screeds of other debugging output > which results from having this class set to debug (eg dumping of all > instance documents). Sure this is all useful in it's own right, but it's a > bit heavyweight just to find out you've misspelt a URL in your submission > target. Certainly I couldn't turn this on by default in a production > environment, whereas I do really need submission errors logged as standard > in production. > > How about logging submission errors to a more specific logger (eg > org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent)? > This could then be reasonably enabled full-time. > > Personally I'd argue this logger be turned on by default because it's flat > out impossible to determine the cause of an xforms-submit-error any other > way. And there's nothing more frustrating - particularly for first time > XForms authors - than watching absolutely nothing happen when you click on a > 'Save' button: no errors displayed, no errors logged. > > Adrian > > Erik Bruchez wrote: > Duane, > > This is an excellent question. > > From the XForms spec's point of view, if submission fails, an > xforms-submit-error event is thrown and that's it, which is not extremely > helpful. Some tips: > > 1. If you are using XML schema for instance validation and suspect that > validation may be failing because validation doesn't pass, try using an > online schema validator with your submitted XForms instance. > > 2. You can enable server-side logging for XForms with: > > <category > name="org.orbeon.oxf.xforms.processor.XFormsServer"> > <priority value="debug"/> > </category> > > in log4j.xml, the XForms instance that failed to be saved will be logged > with some annotations. > > This can help a little bit, but I agree that this is not enough. We have an > RFE for a client-side XForms console, which would be the right place to > provide useful information about submission: > > http://forge.objectweb.org/tracker/index.php?func=detail&aid=304142&group_id=168&atid=350210 > > This will be post-3.0 however. > > -Erik > > Duane Gran wrote: > > Is there anyway to get a more elaborate error message for an xforms- > submit-error event? I find that I spend a lot of time feeling in the dark > for simple mistakes I make which prevent the form from saving. Although I > capture the event successfully, I'm often at a loss about the cause of the > error. > > Duane > > > ________________________________ > > > -- > You receive this message as a subscriber of the [hidden email] > mailing list. > To unsubscribe: mailto:[hidden email] > For general help: mailto:[hidden email]?subject=help > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws > > > > > -- > You receive this message as a subscriber of the [hidden email] > mailing list. > To unsubscribe: mailto:[hidden email] > For general help: mailto:[hidden email]?subject=help > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws > > > -- Blog (XML, Web apps, Open Source): http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
I finally got around to doing this, since we couldn't deploy to
production environments with the
org.orbeon.oxf.xforms.processor.XFormsServer logger set to debug (far
too verbose), but yet we were missing xforms-submit-error events which
were silently causing forms to behave badly.
What I've done is split out some of the XFormsServer debug calls to two other loggers: - org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent By default logs the *message only* of the exception causing an xforms-submit-error at INFO level. Setting to DEBUG will log the entire stack trace of the exception. - org.orbeon.oxf.xforms.XFormsModelSubmission By default logs nothing. Setting this to DEBUG will debug invalid instance documents. So this gives slightly finer control over logging & debugging XForms. The default settings should be roughly suitable for a production environment where you still want errors like a 404 (eg a remote server is down etc) logged, but little more. If you want to debug validation problems in a form the XFormsModelSubmission logger can be used for this, without necessarily having to go to the level of XFormsServer, which logs every instance document every time there's an interaction (useful in it's on right, but makes it hard to pick stuff out of the noise). The downside is is that by default you will get a INFO message every time someone tries to submit a form with invalid data, but this comes back to the general XForms issue of detecting whether xforms-submit-error is caused by a remote server issue or a validation issue. Adrian Alessandro Vernet wrote: Adrian, I also think it is reasonable to have submission error logged by default, that is: in "info" priority. And as you say, we could log them with a separate logger, so one could disable those if needed. Erik what is your take on this? Alex On 2/27/06, Adrian Baker [hidden email] wrote:Option [2] (enabling debugging for org.orbeon.oxf.xforms.processor.XFormsServer) is certainly helpful. But it's pretty imprecise, because of the screeds of other debugging output which results from having this class set to debug (eg dumping of all instance documents). Sure this is all useful in it's own right, but it's a bit heavyweight just to find out you've misspelt a URL in your submission target. Certainly I couldn't turn this on by default in a production environment, whereas I do really need submission errors logged as standard in production. How about logging submission errors to a more specific logger (eg org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent)? This could then be reasonably enabled full-time. Personally I'd argue this logger be turned on by default because it's flat out impossible to determine the cause of an xforms-submit-error any other way. And there's nothing more frustrating - particularly for first time XForms authors - than watching absolutely nothing happen when you click on a 'Save' button: no errors displayed, no errors logged. Adrian Erik Bruchez wrote: Duane, This is an excellent question. From the XForms spec's point of view, if submission fails, an xforms-submit-error event is thrown and that's it, which is not extremely helpful. Some tips: 1. If you are using XML schema for instance validation and suspect that validation may be failing because validation doesn't pass, try using an online schema validator with your submitted XForms instance. 2. You can enable server-side logging for XForms with: <category name="org.orbeon.oxf.xforms.processor.XFormsServer"> <priority value="debug"/> </category> in log4j.xml, the XForms instance that failed to be saved will be logged with some annotations. This can help a little bit, but I agree that this is not enough. We have an RFE for a client-side XForms console, which would be the right place to provide useful information about submission: http://forge.objectweb.org/tracker/index.php?func=detail&aid=304142&group_id=168&atid=350210 This will be post-3.0 however. -Erik Duane Gran wrote: Is there anyway to get a more elaborate error message for an xforms- submit-error event? I find that I spend a lot of time feeling in the dark for simple mistakes I make which prevent the form from saving. Although I capture the event successfully, I'm often at a loss about the cause of the error. Duane ________________________________ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: [hidden email] For general help: [hidden email] ObjectWeb mailing lists service home page: http://www.objectweb.org/wws -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: [hidden email] For general help: [hidden email] ObjectWeb mailing lists service home page: http://www.objectweb.org/wws-- Blog (XML, Web apps, Open Source): http://www.orbeon.com/blog/ <!-- Copyright (C) 2004 Orbeon, Inc. 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.1 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. The full text of the license is available at http://www.gnu.org/copyleft/lesser.html --> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" xmlns="http://jakarta.apache.org/log4j/"> <!-- This is the standard log appender to the console (System.out) --> <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{ISO8601} %-5p %c %x - %m%n"/> </layout> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="LevelMin" value="debug" /> </filter> </appender> <!-- Chainsaw is a graphical appender--> <appender name="ChainsawAppender" class="org.apache.log4j.net.SocketAppender"> <param name="RemoteHost" value="localhost"/> <param name="Port" value="4445"/> <param name="LocationInfo" value="true"/> </appender> <!-- This is the OPS Studio monitor --> <appender name="OPSMonitor" class="org.apache.log4j.net.SocketHubAppender"> <param name="Port" value="4446"/> <param name="LocationInfo" value="true"/> <filter class="org.apache.log4j.varia.LevelRangeFilter"> <param name="LevelMin" value="debug" /> </filter> </appender> <!-- Logging to file, typically used in production --> <appender name="FileAppender" class="org.apache.log4j.FileAppender"> <param name="File" value="l:/OXF/oxf.log"/> <param name="Append" value="false" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/> </layout> </appender> <!-- <category name="org.orbeon.oxf.processor.xmldb.XMLDBProcessor"> <priority value="debug"/> </category> <category name="org.orbeon.oxf.processor.sql.SQLProcessor"> <priority value="debug"/> </category> <category name="org.orbeon.oxf.xforms.processor.XFormsServer"> <priority value="debug"/> </category> <!- Setting this logger to debug will log instance documents which fail validaiton on submission, annotated to indicate invalid/irrelevant nodes, which can be useful when solving issues with forms which fail validation for no apparent reason. -> <category name="org.orbeon.oxf.xforms.XFormsModelSubmission"> <priority value="debug"/> </category> <!- By default, messages of exceptions causing xforms-submit-error events are logged at the INFO level. Setting this logger to debug will log the entire stack trace of these exceptions. If you wish to supress the logging of these messages altogether, set this logger to ERROR level or higher. -> <category name="org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent"> <priority value="debug"/> </category> <category name="org.orbeon.oxf.processor.PageFlowControllerProcessor"> <priority value="debug"/> </category> <category name="org.orbeon.oxf.processor.generator.RequestGenerator"> <priority value="debug"/> </category> <category name="org.orbeon.oxf.webapp.OPSSessionListener"> <priority value="info"/> </category> <category name="org.orbeon.oxf.webapp.OPSServletContextListener"> <priority value="info"/> </category> --> <!-- This is the root logger --> <root> <priority value="info"/> <!--<appender-ref ref="ConsoleAppender"/>--> <!--<appender-ref ref="ChainsawAppender"/>--> <appender-ref ref="OPSMonitor"/> </root> </log4j:configuration> /** * Copyright (C) 2005 Orbeon, Inc. * * 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.1 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. * * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html */ package org.orbeon.oxf.xforms.event.events; import org.apache.log4j.Logger; import org.orbeon.oxf.util.LoggerFactory; import org.orbeon.oxf.xforms.event.XFormsEvent; import org.orbeon.oxf.xforms.event.XFormsEventTarget; import org.orbeon.oxf.xforms.event.XFormsEvents; import org.orbeon.oxf.common.OXFException; import java.io.PrintWriter; import java.io.CharArrayWriter; /** * 4.4.19 The xforms-submit-error Event * * Target: model / Bubbles: Yes / Cancelable: No / Context Info: The submit method URI that failed (xsd:anyURI) * The default action for this event results in the following: None; notification event only. */ public class XFormsSubmitErrorEvent extends XFormsEvent { public final static Logger logger = LoggerFactory.createLogger(XFormsSubmitErrorEvent.class); private final Throwable throwable; private final String urlString; public XFormsSubmitErrorEvent(final XFormsEventTarget targetObject, String urlString, final Throwable throwable) { super(XFormsEvents.XFORMS_SUBMIT_ERROR, targetObject, true, false); this.urlString = urlString; this.throwable = throwable; // Log exception if (logger.isInfoEnabled()) { logger.info("(target='" + targetObject.getId() + "'): " + OXFException.getRootThrowable(throwable).getMessage()); } else if(logger.isDebugEnabled()) { CharArrayWriter writer = new CharArrayWriter(); OXFException.getRootThrowable(throwable).printStackTrace(new PrintWriter(writer)); logger.debug("(target='" + targetObject.getId() + "'): " + writer.toString()); } } public Throwable getThrowable() { return throwable; } public String getUrlString() { return urlString; } } /** * Copyright (C) 2005 Orbeon, Inc. * * 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.1 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. * * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html */ package org.orbeon.oxf.xforms; import org.apache.log4j.Logger; import org.dom4j.*; import org.dom4j.io.DocumentSource; import org.orbeon.oxf.common.OXFException; import org.orbeon.oxf.pipeline.api.ExternalContext; import org.orbeon.oxf.pipeline.api.PipelineContext; import org.orbeon.oxf.processor.ProcessorUtils; import org.orbeon.oxf.util.LoggerFactory; import org.orbeon.oxf.util.NetUtils; import org.orbeon.oxf.xforms.action.XFormsActionInterpreter; import org.orbeon.oxf.xforms.controls.UploadControlInfo; import org.orbeon.oxf.xforms.event.*; import org.orbeon.oxf.xforms.event.events.*; import org.orbeon.oxf.xforms.mip.BooleanModelItemProperty; import org.orbeon.oxf.xforms.mip.ValidModelItemProperty; import org.orbeon.oxf.xml.TransformerUtils; import org.orbeon.oxf.xml.XMLConstants; import org.orbeon.oxf.xml.XMLUtils; import org.orbeon.oxf.xml.dom4j.Dom4jUtils; import org.orbeon.oxf.xml.dom4j.LocationData; import org.orbeon.oxf.xml.dom4j.LocationDocumentResult; import javax.xml.transform.Transformer; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.*; import java.net.URI; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Represents an XForms model submission instance. * * TODO: This badly needs to be modularized instead of being a soup of "ifs"! */ public class XFormsModelSubmission implements XFormsEventTarget, XFormsEventHandlerContainer { public final static Logger logger = LoggerFactory.createLogger(XFormsModelSubmission.class); private final XFormsContainingDocument containingDocument; private final String id; private final XFormsModel model; private final Element submissionElement; private boolean submissionElementExtracted = false; // Event handlers private final List eventHandlers; private String avtAction; // required private String resolvedAction; private String method; // required private boolean validate = true; private boolean relevant = true; private String version; private boolean indent; private String mediatype; private String encoding; private boolean omitxmldeclaration; private Boolean standalone; private String cdatasectionelements; private String replace = XFormsConstants.XFORMS_SUBMIT_REPLACE_ALL; private String replaceInstanceId; private String separator = ";"; private String includenamespaceprefixes; private String avtXXFormsUsername; private String resolvedXXFormsUsername; private String avtXXFormsPassword; private String resolvedXXFormsPassword; public XFormsModelSubmission(XFormsContainingDocument containingDocument, String id, Element submissionElement, XFormsModel model) { this.containingDocument = containingDocument; this.id = id; this.submissionElement = submissionElement; this.model = model; // Extract event handlers eventHandlers = XFormsEventHandlerImpl.extractEventHandlers(containingDocument, this, submissionElement); } public XFormsContainingDocument getContainingDocument() { return containingDocument; } public Element getSubmissionElement() { return submissionElement; } private void extractSubmissionElement() { if (!submissionElementExtracted) { avtAction = submissionElement.attributeValue("action"); method = submissionElement.attributeValue("method"); method = Dom4jUtils.qNameToexplodedQName(Dom4jUtils.extractAttributeValueQName(submissionElement, "method")); validate = !"false".equals(submissionElement.attributeValue("validate")); relevant = !"false".equals(submissionElement.attributeValue("relevant")); version = submissionElement.attributeValue("version"); if (submissionElement.attributeValue("indent") != null) { indent = Boolean.valueOf(submissionElement.attributeValue("indent")).booleanValue(); } mediatype = submissionElement.attributeValue("mediatype"); encoding = submissionElement.attributeValue("encoding"); if (submissionElement.attributeValue("omitxmldeclaration") != null) { omitxmldeclaration = Boolean.valueOf(submissionElement.attributeValue("omit-xml-declaration")).booleanValue(); } if (submissionElement.attributeValue("standalone") != null) { standalone = new Boolean(submissionElement.attributeValue("standalone")); } cdatasectionelements = submissionElement.attributeValue("cdata-section-elements"); if (submissionElement.attributeValue("replace") != null) { replace = submissionElement.attributeValue("replace"); if (replace.equals("instance")) { replaceInstanceId = submissionElement.attributeValue("instance"); } } if (submissionElement.attributeValue("separator") != null) { separator = submissionElement.attributeValue("separator"); } includenamespaceprefixes = submissionElement.attributeValue("includenamespaceprefixes"); // Extension: username and password avtXXFormsUsername = submissionElement.attributeValue(XFormsConstants.XXFORMS_USERNAME_QNAME); avtXXFormsPassword = submissionElement.attributeValue(XFormsConstants.XXFORMS_PASSWORD_QNAME); // Remember that we did this submissionElementExtracted = true; } } private boolean isMethodOptimizedLocalSubmission() { return method.startsWith(XMLUtils.buildExplodedQName(XFormsConstants.XXFORMS_NAMESPACE_URI, "")) && (XFormsSubmissionUtils.isGet(method) || XFormsSubmissionUtils.isPost(method) || XFormsSubmissionUtils.isPut(method)); } public String getId() { return id; } public LocationData getLocationData() { return (LocationData) submissionElement.getData(); } public XFormsEventHandlerContainer getParentContainer() { return model; } public List getEventHandlers() { return eventHandlers; } public void performDefaultAction(PipelineContext pipelineContext, XFormsEvent event) { final String eventName = event.getEventName(); if (XFormsEvents.XFORMS_SUBMIT.equals(eventName) || XFormsEvents.XXFORMS_SUBMIT.equals(eventName)) { // 11.1 The xforms-submit Event // Bubbles: Yes / Cancelable: Yes / Context Info: None containingDocument.setGotSubmission(true); boolean isDeferredSubmissionSecondPass = false; try { // Make sure submission element info is extracted extractSubmissionElement(); final boolean isReplaceAll = replace.equals(XFormsConstants.XFORMS_SUBMIT_REPLACE_ALL); final boolean isReplaceInstance = replace.equals(XFormsConstants.XFORMS_SUBMIT_REPLACE_INSTANCE); final boolean isHandlingOptimizedGet = XFormsUtils.isOptimizeGetAllSubmission() && XFormsSubmissionUtils.isGet(method) && isReplaceAll; //noinspection UnnecessaryLocalVariable final boolean isDeferredSubmission = isReplaceAll; final boolean isDeferredSubmissionFirstPass = isDeferredSubmission && XFormsEvents.XFORMS_SUBMIT.equals(eventName) && !isHandlingOptimizedGet; isDeferredSubmissionSecondPass = isDeferredSubmission && !isDeferredSubmissionFirstPass; // Select node based on ref or bind final XFormsControls xformsControls = containingDocument.getXFormsControls(); xformsControls.setBinding(pipelineContext, submissionElement); // TODO FIXME: the submission element is not a control... final Node currentNode = xformsControls.getCurrentSingleNode(); if (currentNode == null) throw new OXFException("Empty single-node binding on xforms:submission for submission id: " + id); // Evaluate AVTs resolvedAction = XFormsUtils.resolveAttributeValueTemplates(pipelineContext, xformsControls, submissionElement, avtAction); resolvedXXFormsUsername = XFormsUtils.resolveAttributeValueTemplates(pipelineContext, xformsControls, submissionElement, avtXXFormsUsername); resolvedXXFormsPassword = XFormsUtils.resolveAttributeValueTemplates(pipelineContext, xformsControls, submissionElement, avtXXFormsPassword); if (!(currentNode instanceof Document || currentNode instanceof Element)) { throw new OXFException("xforms:submission: single-node binding must refer to a document node or an element."); } final XFormsInstance currentInstance = xformsControls.getCurrentInstance(); final Document initialDocumentToSubmit; if (!isDeferredSubmissionSecondPass) { // Create document to submit final Document backupInstanceDocument = currentInstance.getInstanceDocument(); try { initialDocumentToSubmit = createDocumentToSubmit(currentNode, currentInstance); currentInstance.setInstanceDocument(initialDocumentToSubmit, false); // Revalidate instance containingDocument.dispatchEvent(pipelineContext, new XFormsRevalidateEvent(model, false)); // TODO: The "false" attribute is no longer used. The above will cause events to be // sent out. Check if the validation state can really change. If so, find a // solution. // "no notification events are marked for dispatching due to this operation" // Check that there are no validation errors final boolean instanceSatisfiesValidRequired = isDocumentSatisfiesValidRequired(initialDocumentToSubmit); if (!instanceSatisfiesValidRequired) { // { // currentInstance.readOut(); // } if (logger.isDebugEnabled()) { final LocationDocumentResult documentResult = new LocationDocumentResult(); final TransformerHandler identity = TransformerUtils.getIdentityTransformerHandler(); identity.setResult(documentResult); currentInstance.read(identity); final String documentString = Dom4jUtils.domToString(documentResult.getDocument()); logger.debug("XForms - instance document or subset thereof cannot be submitted:\n" + documentString); } throw new OXFException("xforms:submission: instance to submit does not satisfy valid and/or required model item properties."); } } finally { currentInstance.setInstanceDocument(backupInstanceDocument, false); } } else { initialDocumentToSubmit = null; } // Deferred submission: end of the first pass if (isDeferredSubmissionFirstPass) { // When replace="all", we wait for the submission of an XXFormsSubmissionEvent from the client containingDocument.setClientActiveSubmission(this); return; } final Document documentToSubmit; if (isDeferredSubmissionSecondPass) { // Handle uploaded files if any final Element filesElement = (event instanceof XXFormsSubmissionEvent) ? ((XXFormsSubmissionEvent) event).getFilesElement() : null; if (filesElement != null) { for (Iterator i = filesElement.elements().iterator(); i.hasNext();) { final Element parameterElement = (Element) i.next(); final String name = parameterElement.element("name").getTextTrim(); final Element valueElement = parameterElement.element("value"); final String value = valueElement.getTextTrim(); // An empty value likely means that the user did not select a file. In this case, we don't // want to override an existing value in the instance. Clearing the value in the instance // will have to be done by other means, like a "clear file" button. if (value.length() == 0) continue; final String paramValueType = Dom4jUtils.qNameToexplodedQName(Dom4jUtils.extractAttributeValueQName(valueElement, XMLConstants.XSI_TYPE_QNAME)); final String filename = parameterElement.element("filename").getTextTrim(); final String mediatype = parameterElement.element("content-type").getTextTrim(); final String size = parameterElement.element("content-length").getTextTrim(); final UploadControlInfo uploadControl = (UploadControlInfo) containingDocument.getObjectById(pipelineContext, name); if (uploadControl != null) { // in case of xforms:repeat, the name of the template will not match an existing control // Set value into the instance xformsControls.setBinding(pipelineContext, uploadControl); { final Node currentSingleNode = xformsControls.getCurrentSingleNode(); XFormsInstance.setValueForNode(pipelineContext, currentSingleNode, value, paramValueType); } // Handle filename if any if (uploadControl.getFilenameElement() != null) { xformsControls.pushBinding(pipelineContext, uploadControl.getFilenameElement()); final Node currentSingleNode = xformsControls.getCurrentSingleNode(); XFormsInstance.setValueForNode(pipelineContext, currentSingleNode, filename, null); xformsControls.popBinding(); } // Handle mediatype if any if (uploadControl.getMediatypeElement() != null) { xformsControls.pushBinding(pipelineContext, uploadControl.getMediatypeElement()); final Node currentSingleNode = xformsControls.getCurrentSingleNode(); XFormsInstance.setValueForNode(pipelineContext, currentSingleNode, mediatype, null); xformsControls.popBinding(); } // Handle file size if any if (uploadControl.getSizeElement() != null) { xformsControls.pushBinding(pipelineContext, uploadControl.getSizeElement()); final Node currentSingleNode = xformsControls.getCurrentSingleNode(); XFormsInstance.setValueForNode(pipelineContext, currentSingleNode, size, null); xformsControls.popBinding(); } } } } // Create document to submit final Document backupInstanceDocument = currentInstance.getInstanceDocument(); try { documentToSubmit = createDocumentToSubmit(currentNode, currentInstance); currentInstance.setInstanceDocument(documentToSubmit, false); // Revalidate instance containingDocument.dispatchEvent(pipelineContext, new XFormsRevalidateEvent(model, false)); // TODO: The "false" attribute is no longer used. The above will cause events to be // sent out. Check if the validation state can really change. If so, find a // solution. // "no notification events are marked for dispatching due to this operation" // Check that there are no validation errors final boolean instanceSatisfiesValidRequired = isDocumentSatisfiesValidRequired(documentToSubmit); if (!instanceSatisfiesValidRequired) { // currentInstance.readOut();// FIXME: DEBUG throw new OXFException("xforms:submission: instance to submit does not satisfy valid and/or required model item properties."); } } finally { currentInstance.setInstanceDocument(backupInstanceDocument, false); } } else { // Don't recreate document documentToSubmit = initialDocumentToSubmit; } // Serialize // To support: application/xml, application/x-www-form-urlencoded, multipart/related, multipart/form-data final byte[] serializedInstance; final String serializedInstanceString; { if (XFormsSubmissionUtils.isPost(method) || XFormsSubmissionUtils.isPut(method)) { try { final Transformer identity = TransformerUtils.getIdentityTransformer(); TransformerUtils.applyOutputProperties(identity, "xml", version, null, null, encoding, omitxmldeclaration, standalone, indent, 4); // TODO: use cdata-section-elements final ByteArrayOutputStream os = new ByteArrayOutputStream(); identity.transform(new DocumentSource(documentToSubmit), new StreamResult(os)); serializedInstance = os.toByteArray(); } catch (Exception e) { throw new OXFException("xforms:submission: exception while serializing instance to XML.", e); } serializedInstanceString = null; } else if (XFormsSubmissionUtils.isGet(method) || XFormsSubmissionUtils.isDelete(method)) { // Perform "application/x-www-form-urlencoded" serialization serializedInstanceString = createWwwFormUrlEncoded(documentToSubmit); serializedInstance = null; } else if (method.equals("multipart-post")) { // TODO throw new OXFException("xforms:submission: submission method not yet implemented: " + method); } else if (method.equals("form-data-post")) { // TODO throw new OXFException("xforms:submission: submission method not yet implemented: " + method); } else if (method.equals("urlencoded-post")) { throw new OXFException("xforms:submission: deprecated submission method requested: " + method); } else { throw new OXFException("xforms:submission: invalid submission method requested: " + method); } } final ExternalContext externalContext = (ExternalContext) pipelineContext.getAttribute(PipelineContext.EXTERNAL_CONTEXT); // Result information ConnectionResult connectionResult = null; try { if (isReplaceInstance && resolvedAction.startsWith("test:")) { // Test action if (serializedInstance == null) throw new OXFException("Action 'test:' can only be used with POST method."); connectionResult = new ConnectionResult(null); connectionResult.resultCode = 200; connectionResult.resultHeaders = new HashMap(); connectionResult.resultMediaType = "application/xml"; connectionResult.dontHandleResponse = false; connectionResult.resultInputStream = new ByteArrayInputStream(serializedInstance); } else if (isHandlingOptimizedGet) { // GET with replace="all": we can optimize and tell the client to just load the URL connectionResult = doOptimizedGet(pipelineContext, serializedInstanceString); } else if (!NetUtils.urlHasProtocol(resolvedAction) && (externalContext.getRequest().getContainerType().equals("portlet") || (externalContext.getRequest().getContainerType().equals("servlet") && (XFormsUtils.isOptimizeLocalSubmission() || isMethodOptimizedLocalSubmission()) && isReplaceAll))) { // This is an "optimized" submission, i.e. one that does not use an actual // protocol handler to access the resource // NOTE: Optimizing with include() for servlets doesn't allow detecting // errors caused by the included resource, so we don't allow this for now. // NOTE: For portlets, paths are served directly by the portlet, NOT as // resources. // Current limitations: // o Portlets cannot access resources outside the portlet except by using absolute URLs // o Servlets cannot access resources on the same serer but not in the current application // except by using absolute URLs final URI resolvedURI = XFormsUtils.resolveURI(submissionElement, resolvedAction); connectionResult = XFormsSubmissionUtils.doOptimized(pipelineContext, externalContext, this, method, resolvedURI.toString(), mediatype, isReplaceAll, serializedInstance, serializedInstanceString); } else { // This is a regular remote submission going through a protocol handler // Absolute URLs or absolute paths are allowed to a local servlet final String resolvedURL = XFormsUtils.resolveURL(containingDocument, pipelineContext, submissionElement, false, resolvedAction); connectionResult = XFormsSubmissionUtils.doRegular(pipelineContext, externalContext, method, resolvedURL, resolvedXXFormsUsername, resolvedXXFormsPassword, mediatype, isReplaceAll, serializedInstance, serializedInstanceString); } if (!connectionResult.dontHandleResponse) { // Handle response if (connectionResult.resultCode >= 200 && connectionResult.resultCode < 300) {// accept any success code (in particular "201 Resource Created") // Sucessful response final boolean hasContent; { if (connectionResult.resultInputStream == null) { hasContent = false; } else { if (!connectionResult.resultInputStream.markSupported()) connectionResult.resultInputStream = new BufferedInputStream(connectionResult.resultInputStream); connectionResult.resultInputStream.mark(1); hasContent = connectionResult.resultInputStream.read() != -1; connectionResult.resultInputStream.reset(); } } if (hasContent) { // There is a body if (isReplaceAll) { // When we get here, we are in a mode where we need to send the reply // directly to an external context, if any. // "the event xforms-submit-done is dispatched" containingDocument.dispatchEvent(pipelineContext, new XFormsSubmitDoneEvent(XFormsModelSubmission.this)); final ExternalContext.Response response = externalContext.getResponse(); // Forward headers to response if (connectionResult.resultHeaders != null) { for (Iterator i = connectionResult.resultHeaders.entrySet().iterator(); i.hasNext();) { final Map.Entry currentEntry = (Map.Entry) i.next(); final String headerName = (String) currentEntry.getKey(); final List headerValues = (List) currentEntry.getValue(); if (headerName != null && headerValues != null) { for (Iterator j = headerValues.iterator(); j.hasNext();) { response.addHeader(headerName, (String) j.next()); } } } } // Forward content to response NetUtils.copyStream(connectionResult.resultInputStream, response.getOutputStream()); } else if (isReplaceInstance) { final ByteArrayOutputStream resultByteArrayOutputStream = new ByteArrayOutputStream(); NetUtils.copyStream(connectionResult.resultInputStream, resultByteArrayOutputStream); byte[] submissionResponse = resultByteArrayOutputStream.toByteArray(); if (ProcessorUtils.isXMLContentType(connectionResult.resultMediaType)) { // Handling of XML media type try { final Transformer identity = TransformerUtils.getIdentityTransformer(); final LocationDocumentResult documentResult = new LocationDocumentResult(); identity.transform(new StreamSource(new ByteArrayInputStream(submissionResponse)), documentResult); final Document resultingInstanceDocument = documentResult.getDocument(); // Set new instance document to replace the one submitted final XFormsInstance replaceInstance = (replaceInstanceId == null) ? currentInstance : model.getInstance(replaceInstanceId); if (replaceInstance == null) { containingDocument.dispatchEvent(pipelineContext, new XFormsBindingExceptionEvent(XFormsModelSubmission.this)); } else { // Set new instance replaceInstance.setInstanceDocument(resultingInstanceDocument, true); // Mark all values as changed so that refresh sends appropriate events XFormsUtils.markAllValuesChanged(replaceInstance.getInstanceDocument()); // Handle new instance and associated events model.handleNewInstanceDocuments(pipelineContext); // Notify that submission is done containingDocument.dispatchEvent(pipelineContext, new XFormsSubmitDoneEvent(XFormsModelSubmission.this)); } } catch (Exception e) { throw new OXFException("xforms:submission: exception while serializing XML to instance.", e); } } else { // Other media type throw new OXFException("Body received with non-XML media type for replace=\"instance\": " + connectionResult.resultMediaType); } } else if (replace.equals(XFormsConstants.XFORMS_SUBMIT_REPLACE_NONE)) { // Just notify that processing is terminated containingDocument.dispatchEvent(pipelineContext, new XFormsSubmitDoneEvent(XFormsModelSubmission.this)); } else { throw new OXFException("xforms:submission: invalid replace attribute: " + replace); } } else { // There is no body, notify that processing is terminated containingDocument.dispatchEvent(pipelineContext, new XFormsSubmitDoneEvent(XFormsModelSubmission.this)); } } else if (connectionResult.resultCode == 302 || connectionResult.resultCode == 301) { // Got a redirect final ExternalContext.Response response = externalContext.getResponse(); // Forward headers to response // TODO: this is duplicated from above if (connectionResult.resultHeaders != null) { for (Iterator i = connectionResult.resultHeaders.entrySet().iterator(); i.hasNext();) { final Map.Entry currentEntry = (Map.Entry) i.next(); final String headerName = (String) currentEntry.getKey(); final List headerValues = (List) currentEntry.getValue(); if (headerName != null && headerValues != null) { for (Iterator j = headerValues.iterator(); j.hasNext();) { response.addHeader(headerName, (String) j.next()); } } } } // Forward redirect response.setStatus(connectionResult.resultCode); } else { // Error code received throw new OXFException("Error code received when submitting instance: " + connectionResult.resultCode); } } } finally { // Clean-up if (connectionResult != null) { connectionResult.close(); } } } catch (Throwable e) { if (isDeferredSubmissionSecondPass && XFormsUtils.isOptimizePostAllSubmission()) { // It doesn't serve any purpose here to dispatch an event, so we just propagate the exception throw new OXFException(e); } else { // Any exception will cause an error event to be dispatched containingDocument.dispatchEvent(pipelineContext, new XFormsSubmitErrorEvent(XFormsModelSubmission.this, resolvedAction, e)); } } } else if (XFormsEvents.XFORMS_BINDING_EXCEPTION.equals(eventName)) { // The default action for this event results in the following: Fatal error. throw new OXFException("Binding exception."); } } private ConnectionResult doOptimizedGet(PipelineContext pipelineContext, String serializedInstanceString) { final String actionString = resolvedAction + ((resolvedAction.indexOf('?') == -1) ? "?" : "") + serializedInstanceString; final String resultURL = XFormsActionInterpreter.resolveLoadValue(containingDocument, pipelineContext, submissionElement, true, actionString, null, null); final ConnectionResult connectionResult = new ConnectionResult(resultURL); connectionResult.dontHandleResponse = true; return connectionResult; } private Document createDocumentToSubmit(final Node currentNode, final XFormsInstance currentInstance) { // "A node from the instance data is selected, based on attributes on the submission // element. The indicated node and all nodes for which it is an ancestor are considered for // the remainder of the submit process. " final Document documentToSubmit; if (currentNode instanceof Element) { // Create subset of document documentToSubmit = Dom4jUtils.createDocument((Element) currentNode); } else { // Use entire instance document documentToSubmit = Dom4jUtils.createDocument(currentInstance.getInstanceDocument().getRootElement()); } if (relevant) { // "Any node which is considered not relevant as defined in 6.1.4 is removed." final Node[] nodeToDetach = new Node[1]; do { // NOTE: This is not very efficient, but at least we avoid NPEs that we would get by // detaching elements within accept(). Should implement a more efficient algorithm to // prune non-relevant nodes. nodeToDetach[0] = null; documentToSubmit.accept(new VisitorSupport() { public final void visit(Element element) { checkInstanceData(element); } public final void visit(Attribute attribute) { checkInstanceData(attribute); } private final void checkInstanceData(Node node) { if (nodeToDetach[0] == null) { final InstanceData instanceData = XFormsUtils.getInstanceDataUpdateInherited(node); // Check "relevant" MIP and remove non-relevant nodes { final BooleanModelItemProperty relevantMIP = instanceData.getInheritedRelevant(); if (relevantMIP != null && !relevantMIP.get()) nodeToDetach[0] = node; } } } }); if (nodeToDetach[0] != null) nodeToDetach[0].detach(); } while (nodeToDetach[0] != null); } // TODO: handle includenamespaceprefixes return documentToSubmit; } private String createWwwFormUrlEncoded(final Document document) { final StringBuffer sb = new StringBuffer(); document.accept(new VisitorSupport() { public final void visit(Element element) { // We only care about elements final List children = element.elements(); if (children == null || children.size() == 0) { // Only consider leaves final String text = element.getText(); if (text != null && text.length() > 0) { // Got one! final String localName = element.getName(); if (sb.length() > 0) sb.append(separator); try { sb.append(URLEncoder.encode(localName, "utf-8")); sb.append('='); sb.append(URLEncoder.encode(text, "utf-8")); // TODO: check if line breaks will be correcly encoded as "%0D%0A" } catch (UnsupportedEncodingException e) { // Should not happen: utf-8 must be supported throw new OXFException(e); } } } } }); return sb.toString(); } private boolean isDocumentSatisfiesValidRequired(final Document documentToSubmit) { final boolean[] instanceSatisfiesValidRequired = new boolean[]{true}; if (validate) { documentToSubmit.accept(new VisitorSupport() { public final void visit(Element element) { final InstanceData instanceData = XFormsUtils.getLocalInstanceData(element); final boolean valid = checkInstanceData(instanceData); instanceSatisfiesValidRequired[0] &= valid; if (!valid && logger.isDebugEnabled()) { logger.debug("Found invalid element: " + element.getQName() + ", value:" + element.getText()); } } public final void visit(Attribute attribute) { final InstanceData instanceData = XFormsUtils.getLocalInstanceData(attribute); final boolean valid = checkInstanceData(instanceData); instanceSatisfiesValidRequired[0] &= valid; if (!valid && logger.isDebugEnabled()) { logger.debug("Found invalid attribute: " + attribute.getQName() + ", value:" + attribute.getValue()); } } private final boolean checkInstanceData(InstanceData instanceData) { // Check "valid" MIP { final BooleanModelItemProperty validMIP = instanceData.getValid(); if (validMIP != null && !validMIP.get()) return false; } // Check "required" MIP { final ValidModelItemProperty requiredMIP = instanceData.getRequired(); if (requiredMIP != null && requiredMIP.get() && requiredMIP.getStringValue().length() == 0) { // Required and empty return false; } } return true; } }); } return instanceSatisfiesValidRequired[0]; } public static class ConnectionResult { public boolean dontHandleResponse; public int resultCode; public String resultMediaType; public InputStream resultInputStream; public Map resultHeaders; public String resourceURI; public ConnectionResult(String resourceURI) { this.resourceURI = resourceURI; } public void close() {} } } class ResponseAdapter implements ExternalContext.Response { private Object nativeResponse; private int status = 200; private String contentType; private StringWriter stringWriter; private PrintWriter printWriter; private LocalByteArrayOutputStream byteStream; private InputStream inputStream; public ResponseAdapter(Object nativeResponse) { this.nativeResponse = nativeResponse; } public int getResponseCode() { return status; } public String getContentType() { return contentType; } public Map getHeaders() { return null; } public InputStream getInputStream() { if (inputStream == null) { if (stringWriter != null) { throw new OXFException("ResponseAdapter.getInputStream() does not yet support content written with getWriter()."); } else if (byteStream != null) { inputStream = new ByteArrayInputStream(byteStream.getByteArray(), 0, byteStream.size()); } } return inputStream; } public void addHeader(String name, String value) { } public boolean checkIfModifiedSince(long lastModified, boolean allowOverride) { return true; } public String getCharacterEncoding() { return null; } public String getNamespacePrefix() { return null; } public OutputStream getOutputStream() throws IOException { if (byteStream == null) byteStream = new LocalByteArrayOutputStream(); return byteStream; } public PrintWriter getWriter() throws IOException { if (stringWriter == null) { stringWriter = new StringWriter(); printWriter = new PrintWriter(stringWriter); } return printWriter; } public boolean isCommitted() { return false; } public void reset() { } public String rewriteActionURL(String urlString) { return null; } public String rewriteRenderURL(String urlString) { return null; } public String rewriteResourceURL(String urlString, boolean absolute) { return null; } public void sendError(int sc) throws IOException { this.status = sc; } public void sendRedirect(String pathInfo, Map parameters, boolean isServerSide, boolean isExitPortal) throws IOException { } public void setCaching(long lastModified, boolean revalidate, boolean allowOverride) { } public void setContentLength(int len) { } public void setContentType(String contentType) { this.contentType = contentType; } public void setHeader(String name, String value) { } public void setStatus(int status) { this.status = status; } public void setTitle(String title) { } private static class LocalByteArrayOutputStream extends ByteArrayOutputStream { public byte[] getByteArray() { return buf; } } public Object getNativeResponse() { return nativeResponse; } } -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Adrian,
Thanks, that sounds quite reasonable. Wouldn't it be enough to just have the extra XFormsModelSubmission, and log the 404, etc. to the usual XFormsServer logger? -Erik Adrian Baker wrote: > I finally got around to doing this, since we couldn't deploy to > production environments with the > org.orbeon.oxf.xforms.processor.XFormsServer logger set to debug (far > too verbose), but yet we were missing xforms-submit-error events which > were silently causing forms to behave badly. > > What I've done is split out some of the XFormsServer debug calls to two > other loggers: > > - org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent > By default logs the *message only* of the exception causing an > xforms-submit-error at INFO level. Setting to DEBUG will log the entire > stack trace of the exception. > > - org.orbeon.oxf.xforms.XFormsModelSubmission > By default logs nothing. Setting this to DEBUG will debug invalid > instance documents. > > So this gives slightly finer control over logging & debugging XForms. > The default settings should be roughly suitable for a production > environment where you still want errors like a 404 (eg a remote server > is down etc) logged, but little more. If you want to debug validation > problems in a form the XFormsModelSubmission logger can be used for > this, without necessarily having to go to the level of XFormsServer, > which logs every instance document every time there's an interaction > (useful in it's on right, but makes it hard to pick stuff out of the noise). > > The downside is is that by default you will get a INFO message every > time someone tries to submit a form with invalid data, but this comes > back to the general XForms issue of detecting whether > xforms-submit-error is caused by a remote server issue or a validation > issue. > > Adrian -- Orbeon - XForms Everywhere: http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Adrian Erik Bruchez wrote: Adrian, -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Did this get forgotten at some point, or was it decided that
xforms-submit-error should not result in a log message?
Adrian Baker wrote:
-- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws |
Administrator
|
Hi Adrian,
It is not forgotten. At least not completely :). But just to make, let's create an entry in the tracker about this: http://forge.objectweb.org/tracker/index.php?func=detail&aid=305949&group_id=168&atid=350207 Alex On 8/6/06, Adrian Baker <[hidden email]> wrote: > > Did this get forgotten at some point, or was it decided that > xforms-submit-error should not result in a log message? > > > Adrian Baker wrote: > Log to XFormsServer at info level you mean? That would work, sure. But the > disadvantage would be that if you wanted to suppress xforms-submit-error > messages being logged you also have to suppress all other INFO level > XFormsServer messages. > > Adrian > > Erik Bruchez wrote: > Adrian, > > Thanks, that sounds quite reasonable. Wouldn't it be enough to just > have the extra XFormsModelSubmission, and log the 404, etc. to the > usual XFormsServer logger? > > -Erik > > Adrian Baker wrote: > > I finally got around to doing this, since we couldn't deploy to > > production environments with the > > org.orbeon.oxf.xforms.processor.XFormsServer logger set > to debug (far > > too verbose), but yet we were missing xforms-submit-error events which > > were silently causing forms to behave badly. > > > > What I've done is split out some of the XFormsServer debug calls to two > > other loggers: > > > > - > org.orbeon.oxf.xforms.event.events.XFormsSubmitErrorEvent > > By default logs the *message only* of the exception causing an > > xforms-submit-error at INFO level. Setting to DEBUG will log the entire > > stack trace of the exception. > > > > - org.orbeon.oxf.xforms.XFormsModelSubmission > > By default logs nothing. Setting this to DEBUG will debug invalid > > instance documents. > > > > So this gives slightly finer control over logging & debugging XForms. > > The default settings should be roughly suitable for a production > > environment where you still want errors like a 404 (eg a remote server > > is down etc) logged, but little more. If you want to debug validation > > problems in a form the XFormsModelSubmission logger can be used for > > this, without necessarily having to go to the level of XFormsServer, > > which logs every instance document every time there's an interaction > > (useful in it's on right, but makes it hard to pick stuff out of the > noise). > > > > The downside is is that by default you will get a INFO message every > > time someone tries to submit a form with invalid data, but this comes > > back to the general XForms issue of detecting whether > > xforms-submit-error is caused by a remote server issue or a validation > > issue. > > > > Adrian > > ________________________________ > > > -- > You receive this message as a subscriber of the [hidden email] > mailing list. > To unsubscribe: mailto:[hidden email] > For general help: mailto:[hidden email]?subject=help > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit > http://www.messagelabs.com/email > ______________________________________________________________________ > > ________________________________ > > -- You receive this message as a subscriber of the [hidden email] > mailing list. To unsubscribe: > mailto:[hidden email] > For general help: mailto:[hidden email]?subject=help > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws > > > > -- > You receive this message as a subscriber of the [hidden email] > mailing list. > To unsubscribe: mailto:[hidden email] > For general help: mailto:[hidden email]?subject=help > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws > > > -- Blog (XML, Web apps, Open Source): http://www.orbeon.com/blog/ -- You receive this message as a subscriber of the [hidden email] mailing list. To unsubscribe: mailto:[hidden email] For general help: mailto:[hidden email]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
--
Follow Orbeon on Twitter: @orbeon Follow me on Twitter: @avernet |
Free forum by Nabble | Edit this page |