]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-2391, 2503, 4201, 4202, 4204, 4206 More work on reporting to handle parameters...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Fri, 15 Jul 2011 20:47:29 +0000 (20:47 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Fri, 15 Jul 2011 20:47:29 +0000 (20:47 +0000)
services/common/src/main/cspace/config/services/tenants/tenant-bindings-proto.xml
services/common/src/main/java/org/collectionspace/services/common/storage/JDBCTools.java
services/report/3rdparty/build.xml
services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jasper [new file with mode: 0644]
services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jrxml [new file with mode: 0644]
services/report/service/src/main/java/org/collectionspace/services/report/ReportResource.java
services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportConstants.java
services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportPostInitHandler.java [new file with mode: 0644]

index 703926ed1efb839baaa836efaecb3249da68ff65..c596d3748e36151f85d4eac934932caf44cf3488 100644 (file)
       <service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
       <service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.report.nuxeo.ReportDocumentModelHandler</service:documentHandler>
       <service:validatorHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.report.nuxeo.ReportValidatorHandler</service:validatorHandler>
+      <service:initHandler xmlns:service="http://collectionspace.org/services/common/service">
+        <service:classname>org.collectionspace.services.report.nuxeo.ReportPostInitHandler</service:classname>
+        <service:params>
+          <service:property>
+            <service:key>readerRoleName</service:key>
+            <service:value>reader</service:value>
+          </service:property>
+        </service:params>
+      </service:initHandler>
       <service:object xmlns:service="http://collectionspace.org/services/common/service" name="Report" version="0.1">
         <service:part id="0" control_group="Managed" versionable="true" auditable="false" label="reports-system" updated="" order="0">
           <service:content contentType="application/xml">
index e145b2ef548eec51b828a358beffaaacf4b60c71..125bc65b08b34d85ed174066c40eaae713cb5fad 100755 (executable)
@@ -79,6 +79,7 @@ public class JDBCTools {
     }\r
 \r
 \r
+    /* THIS IS BROKEN - If you close the statement, it closes the ResultSet!!!\r
     public static ResultSet executeQuery(String repoName, String sql) throws Exception {\r
         Connection conn = null;\r
         Statement stmt = null;\r
@@ -108,7 +109,7 @@ public class JDBCTools {
                 return null;\r
             }\r
         }\r
-    }\r
+    } */\r
 \r
     public static int executeUpdate(String repoName, String sql) throws Exception {\r
         Connection conn = null;\r
index a8e694700f6e85ec9f68219abdc20df2d4e159c8..4929ee80637153deb806d08ed446df13e220a07c 100644 (file)
         </exec>\r
     </target>\r
 \r
+               <target name="deploy_jasper_samples" \r
+                       description="Copy sample jasper files to ${jboss.server.cspace}/cspace/reports">\r
+        <copy todir="${jboss.server.cspace}/cspace/reports">\r
+                                       <fileset dir="${basedir}/jasper-cs-report/src/main/resources"\r
+                                                                       includes="*.jasper"/>\r
+        </copy>\r
+    </target>\r
+\r
     <target name="deploy" depends="install"\r
     description="deploy report in ${jboss.server.nuxeo}">\r
         <ant antfile="nuxeo-platform-cs-report/build.xml" target="deploy" inheritall="false"/>\r
+                               <antcall target="deploy_jasper_samples" />\r
     </target>\r
 \r
     <target name="undeploy"\r
diff --git a/services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jasper b/services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jasper
new file mode 100644 (file)
index 0000000..3c1d6ee
Binary files /dev/null and b/services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jasper differ
diff --git a/services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jrxml b/services/report/3rdparty/jasper-cs-report/src/main/resources/acq_basic.jrxml
new file mode 100644 (file)
index 0000000..466d92f
--- /dev/null
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="acq_single" language="groovy" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
+       <property name="ireport.zoom" value="1.0"/>
+       <property name="ireport.x" value="0"/>
+       <property name="ireport.y" value="0"/>
+       <style name="Title" forecolor="#FFFFFF" fontName="Times New Roman" fontSize="50" isBold="false" pdfFontName="Times-Bold"/>
+       <style name="SubTitle" forecolor="#CCCCCC" fontName="Times New Roman" fontSize="18" isBold="false" pdfFontName="Times-Roman"/>
+       <style name="Column header" forecolor="#666666" fontName="Times New Roman" fontSize="14" isBold="true" pdfFontName="Times-Roman"/>
+       <style name="Detail" mode="Transparent" fontName="Times New Roman" pdfFontName="Times-Roman"/>
+       <style name="Row" mode="Transparent" fontName="Times New Roman" pdfFontName="Times-Roman">
+               <conditionalStyle>
+                       <conditionExpression><![CDATA[$V{REPORT_COUNT}%2 == 0]]></conditionExpression>
+                       <style mode="Opaque" backcolor="#F0EFEF"/>
+               </conditionalStyle>
+       </style>
+       <parameter name="csid" class="java.lang.String" isForPrompting="false">
+               <defaultValueExpression><![CDATA[null]]></defaultValueExpression>
+       </parameter>
+       <parameter name="where_clause" class="java.lang.String" isForPrompting="false">
+               <defaultValueExpression><![CDATA[(($P{csid}==null||($P{csid}.length()==0))?"":" WHERE hierarchy.name = '"+$P{csid}+"'")]]></defaultValueExpression>
+       </parameter>
+       <queryString>
+               <![CDATA[SELECT
+     acquisitions_common."originalobjectpurchasepricevalue" AS acquisitions_common_originalobjectpurchasepricevalue,
+     acquisitions_common."transferoftitlenumber" AS acquisitions_common_transferoftitlenumber,
+     acquisitions_common."acquisitionreferencenumber" AS acquisitions_common_acquisitionreferencenumber,
+     acquisitions_common."acquisitionmethod" AS acquisitions_common_acquisitionmethod,
+     acquisitions_common."acquisitionauthorizerdate" AS acquisitions_common_acquisitionauthorizerdate,
+     acquisitions_common."acquisitionauthorizer" AS acquisitions_common_acquisitionauthorizer,
+     acquisitions_common."accessiondate" AS acquisitions_common_accessiondate,
+     acquisitions_common."acquisitionreason" AS acquisitions_common_acquisitionreason
+FROM
+     "public"."acquisitions_common" acquisitions_common INNER JOIN "public"."hierarchy" hierarchy ON acquisitions_common."id" = hierarchy."id"
+$P!{where_clause}]]>
+       </queryString>
+       <field name="acquisitions_common_originalobjectpurchasepricevalue" class="java.lang.String"/>
+       <field name="acquisitions_common_transferoftitlenumber" class="java.lang.String"/>
+       <field name="acquisitions_common_acquisitionreferencenumber" class="java.lang.String"/>
+       <field name="acquisitions_common_acquisitionmethod" class="java.lang.String"/>
+       <field name="acquisitions_common_acquisitionauthorizerdate" class="java.lang.String"/>
+       <field name="acquisitions_common_acquisitionauthorizer" class="java.lang.String"/>
+       <field name="acquisitions_common_accessiondate" class="java.lang.String"/>
+       <field name="acquisitions_common_acquisitionreason" class="java.lang.String"/>
+       <background>
+               <band splitType="Stretch"/>
+       </background>
+       <title>
+               <band height="102" splitType="Stretch">
+                       <frame>
+                               <reportElement mode="Opaque" x="0" y="0" width="721" height="66" backcolor="#FFFFFF"/>
+                               <staticText>
+                                       <reportElement style="SubTitle" x="370" y="37" width="316" height="29"/>
+                                       <textElement textAlignment="Right">
+                                               <font fontName="Arial" size="22" isBold="false"/>
+                                       </textElement>
+                                       <text><![CDATA[Acquisitions]]></text>
+                               </staticText>
+                               <image>
+                                       <reportElement x="11" y="2" width="366" height="61"/>
+                                       <imageExpression class="java.lang.String"><![CDATA["http://www.collectionspace.org/sites/all/themes/CStheme/images/CSpaceLogo.png"]]></imageExpression>
+                               </image>
+                       </frame>
+                       <frame>
+                               <reportElement mode="Opaque" x="0" y="70" width="721" height="32" forecolor="#000000" backcolor="#66FFFF"/>
+                               <textField pattern="EEEEE dd MMMMM yyyy">
+                                       <reportElement x="553" y="12" width="144" height="20" forecolor="#FFFFFF"/>
+                                       <textElement textAlignment="Right">
+                                               <font size="12"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.util.Date"><![CDATA[new java.util.Date()]]></textFieldExpression>
+                               </textField>
+                       </frame>
+               </band>
+       </title>
+       <pageHeader>
+               <band splitType="Stretch"/>
+       </pageHeader>
+       <columnHeader>
+               <band height="18" splitType="Stretch">
+                       <staticText>
+                               <reportElement style="Column header" x="141" y="0" width="87" height="18" forecolor="#000000"/>
+                               <textElement>
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Orig. Price]]></text>
+                       </staticText>
+                       <staticText>
+                               <reportElement style="Column header" x="2" y="0" width="139" height="18" forecolor="#000000"/>
+                               <textElement textAlignment="Center">
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Ref #]]></text>
+                       </staticText>
+                       <staticText>
+                               <reportElement style="Column header" x="228" y="0" width="75" height="18" forecolor="#000000"/>
+                               <textElement>
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Auth. Date]]></text>
+                       </staticText>
+                       <staticText>
+                               <reportElement style="Column header" x="303" y="0" width="192" height="18" forecolor="#000000"/>
+                               <textElement textAlignment="Center">
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Authorizer]]></text>
+                       </staticText>
+                       <staticText>
+                               <reportElement style="Column header" x="495" y="0" width="169" height="18" forecolor="#000000"/>
+                               <textElement textAlignment="Center">
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Reason]]></text>
+                       </staticText>
+                       <staticText>
+                               <reportElement style="Column header" x="664" y="0" width="72" height="18" forecolor="#000000"/>
+                               <textElement textAlignment="Center">
+                                       <font fontName="Arial" size="13" isBold="true"/>
+                               </textElement>
+                               <text><![CDATA[Method]]></text>
+                       </staticText>
+               </band>
+       </columnHeader>
+       <detail>
+               <band height="18" splitType="Stretch">
+                       <frame>
+                               <reportElement style="Row" mode="Opaque" x="0" y="0" width="797" height="18"/>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="141" y="0" width="87" height="18"/>
+                                       <textElement>
+                                               <font size="13"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[$F{acquisitions_common_originalobjectpurchasepricevalue}]]></textFieldExpression>
+                               </textField>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="2" y="0" width="139" height="18"/>
+                                       <textElement>
+                                               <font size="12"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[$F{acquisitions_common_acquisitionreferencenumber}]]></textFieldExpression>
+                               </textField>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="228" y="0" width="75" height="18"/>
+                                       <textElement>
+                                               <font size="13"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[$F{acquisitions_common_acquisitionauthorizerdate}]]></textFieldExpression>
+                               </textField>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="303" y="0" width="192" height="18"/>
+                                       <textElement textAlignment="Center">
+                                               <font size="13"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[($F{acquisitions_common_acquisitionauthorizer}==null ||
+    $F{acquisitions_common_acquisitionauthorizer}.isEmpty())?
+  "":$F{acquisitions_common_acquisitionauthorizer}.substring(
+     $F{acquisitions_common_acquisitionauthorizer}.lastIndexOf( ")" )+2,
+       $F{acquisitions_common_acquisitionauthorizer}.length()-1).replaceAll("[+]"," ")]]></textFieldExpression>
+                               </textField>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="495" y="0" width="169" height="18"/>
+                                       <textElement textAlignment="Center">
+                                               <font size="13"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[$F{acquisitions_common_acquisitionreason}]]></textFieldExpression>
+                               </textField>
+                               <textField isStretchWithOverflow="true">
+                                       <reportElement style="Detail" positionType="Float" x="664" y="0" width="72" height="18"/>
+                                       <textElement textAlignment="Center">
+                                               <font size="13"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[$F{acquisitions_common_acquisitionmethod}]]></textFieldExpression>
+                               </textField>
+                       </frame>
+               </band>
+       </detail>
+       <columnFooter>
+               <band height="7" splitType="Stretch">
+                       <line>
+                               <reportElement positionType="FixRelativeToBottom" x="0" y="3" width="555" height="1"/>
+                               <graphicElement>
+                                       <pen lineWidth="0.5" lineColor="#999999"/>
+                               </graphicElement>
+                       </line>
+               </band>
+       </columnFooter>
+       <pageFooter>
+               <band height="25" splitType="Stretch">
+                       <frame>
+                               <reportElement mode="Opaque" x="0" y="0" width="802" height="25" forecolor="#D0B48E" backcolor="#000000"/>
+                               <textField evaluationTime="Report">
+                                       <reportElement style="Column header" x="757" y="3" width="40" height="20" forecolor="#FFFFFF"/>
+                                       <textElement verticalAlignment="Middle">
+                                               <font size="10" isBold="false"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA[" " + $V{PAGE_NUMBER}]]></textFieldExpression>
+                               </textField>
+                               <textField>
+                                       <reportElement style="Column header" x="677" y="3" width="80" height="20" forecolor="#FFFFFF"/>
+                                       <textElement textAlignment="Right" verticalAlignment="Middle">
+                                               <font size="10" isBold="false"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.lang.String"><![CDATA["Page "+$V{PAGE_NUMBER}+" of"]]></textFieldExpression>
+                               </textField>
+                               <textField pattern="EEEEE dd MMMMM yyyy">
+                                       <reportElement style="Column header" x="2" y="3" width="197" height="20" forecolor="#FFFFFF"/>
+                                       <textElement verticalAlignment="Middle">
+                                               <font size="10" isBold="false"/>
+                                       </textElement>
+                                       <textFieldExpression class="java.util.Date"><![CDATA[new java.util.Date()]]></textFieldExpression>
+                               </textField>
+                       </frame>
+               </band>
+       </pageFooter>
+       <summary>
+               <band splitType="Stretch"/>
+       </summary>
+</jasperReport>
index 58c23b3e26fa116b78e136aabd92eb40c391a648..0de359d8fa84c2c0de0d63f81d8ccc1a6bb3a54f 100644 (file)
@@ -68,6 +68,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.HashMap;
@@ -120,87 +121,26 @@ public class ReportResource extends ResourceBase {
     @Produces("application/pdf")
     public Response invokeReport(
             @PathParam("csid") String csid) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("invokeReport with csid=" + csid);
-        }
-        Response response = null;
         if (csid == null || "".equals(csid)) {
             logger.error("invokeReport: missing csid!");
-            response = Response.status(Response.Status.BAD_REQUEST).entity(
+            Response response = Response.status(Response.Status.BAD_REQUEST).entity(
                     "invoke failed on Report csid=" + csid).type(
                     "text/plain").build();
             throw new WebApplicationException(response);
         }
+        if (logger.isTraceEnabled()) {
+            logger.trace("invokeReport with csid=" + csid);
+        }
         try {
                ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
             DocumentWrapper<DocumentModel> docWrapper = getRepositoryClient(ctx).getDoc(ctx, csid);
                DocumentModel docModel = docWrapper.getWrappedObject();
                String reportFileName = (String)docModel.getPropertyValue(ReportJAXBSchema.FILENAME);
-               String fullPath = ServiceMain.getInstance().getServerRootDir() +
-                                                       File.separator + ConfigReader.CSPACE_DIR_NAME + 
-                                                       File.separator + REPORTS_FOLDER +
-                                                       File.separator + reportFileName;
-               Connection conn = getConnection();
                HashMap params = new HashMap();
-               FileInputStream fileStream = new FileInputStream(fullPath);
-
-            // fill the report
-               JasperPrint jasperprint = JasperFillManager.fillReport(fileStream, params,conn);
-               // export report to pdf and build a response with the bytes
-               byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
-               response = Response.ok(pdfasbytes, "application/pdf").build();
-        } catch (UnauthorizedException ue) {
-            response = Response.status(
-                    Response.Status.UNAUTHORIZED).entity("Invoke failed reason " + ue.getErrorReason()).type("text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (DocumentNotFoundException dnfe) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("invokeReport", dnfe);
-            }
-            response = Response.status(Response.Status.NOT_FOUND).entity(
-                    "Invoke failed on Report csid=" + csid).type(
-                    "text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (SQLException sqle) {
-            // SQLExceptions can be chained. We have at least one exception, so
-            // set up a loop to make sure we let the user know about all of them
-            // if there happens to be more than one.
-            if (logger.isDebugEnabled()) {
-                   SQLException tempException = sqle;
-                   while (null != tempException) {
-                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
-       
-                       // loop to the next exception
-                       tempException = tempException.getNextException();
-                   }
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity(
-                               "Invoke failed (SQL problem) on Report csid=" + csid).type("text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (JRException jre) {
-            if (logger.isDebugEnabled()) {
-               logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity(
-                               "Invoke failed (Jasper problem) on Report csid=" + csid).type("text/plain").build();
-            throw new WebApplicationException(response);
+               return buildReportResponse(csid, params, reportFileName);
         } catch (Exception e) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("invokeReport", e);
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity("Invoke failed").type("text/plain").build();
-            throw new WebApplicationException(response);
-        }
-        if (response == null) {
-            response = Response.status(Response.Status.NOT_FOUND).entity(
-                    "Invoke failed, the requested Report CSID:" + csid + ": was not found.").type(
-                    "text/plain").build();
-            throw new WebApplicationException(response);
+            throw bigReThrow(e, ServiceMessages.POST_FAILED);
         }
-        return response;
     }
     
     @POST
@@ -256,26 +196,92 @@ public class ReportResource extends ResourceBase {
                                +invocationMode);
                }
                String reportFileName = (String)docModel.getPropertyValue(ReportJAXBSchema.FILENAME);
-               String fullPath = ServiceMain.getInstance().getServerRootDir() +
-                                                       File.separator + ConfigReader.CSPACE_DIR_NAME + 
-                                                       File.separator + REPORTS_FOLDER +
-                                                       // File.separator + tenantName +
-                                                       File.separator + reportFileName;
-               Connection conn = getConnection();
-
-               FileInputStream fileStream = new FileInputStream(fullPath);
 
-            // fill the report
-               JasperPrint jasperprint = JasperFillManager.fillReport(fileStream, params,conn);
-               // export report to pdf and build a response with the bytes
-               byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
-               
-               // Need to set response type for what is requested...
-            Response response = Response.ok(pdfasbytes, "application/pdf").build();
-
-               return response;
+               return buildReportResponse(csid, params, reportFileName);
+        } catch (Exception e) {
+            throw bigReThrow(e, ServiceMessages.POST_FAILED);
+        }
+    }
+    
+    private Response buildReportResponse(String reportCSID, HashMap params, String reportFileName) {
+               Connection conn = null;
+               Response response = null;
+       try {
+                       String fullPath = ServiceMain.getInstance().getServerRootDir() +
+                                                               File.separator + ConfigReader.CSPACE_DIR_NAME + 
+                                                               File.separator + REPORTS_FOLDER +
+                                                               // File.separator + tenantName +
+                                                               File.separator + reportFileName;
+                       conn = getConnection();
+       
+            if (logger.isTraceEnabled()) {
+               logger.trace("ReportResource for Report csid=" + reportCSID
+                               +" opening report file: "+fullPath);
+            }
+                       FileInputStream fileStream = new FileInputStream(fullPath);
+       
+               // fill the report
+                       JasperPrint jasperprint = JasperFillManager.fillReport(fileStream, params,conn);
+                       // export report to pdf and build a response with the bytes
+                       byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
+                       
+                       // Need to set response type for what is requested...
+               response = Response.ok(pdfasbytes, "application/pdf").build();
+       
+               return response;        
+        } catch (SQLException sqle) {
+            // SQLExceptions can be chained. We have at least one exception, so
+            // set up a loop to make sure we let the user know about all of them
+            // if there happens to be more than one.
+            if (logger.isDebugEnabled()) {
+                   SQLException tempException = sqle;
+                   while (null != tempException) {
+                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
+       
+                       // loop to the next exception
+                       tempException = tempException.getNextException();
+                   }
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (JRException jre) {
+            if (logger.isDebugEnabled()) {
+               logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (Jasper problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (FileNotFoundException fnfe) {
+            if (logger.isDebugEnabled()) {
+               logger.debug("FileNotFoundException: " + fnfe.getLocalizedMessage());
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.POST_FAILED);
+               } finally {
+               if(conn!=null) {
+                       try {
+                       conn.close();
+                } catch (SQLException sqle) {
+                    // SQLExceptions can be chained. We have at least one exception, so
+                    // set up a loop to make sure we let the user know about all of them
+                    // if there happens to be more than one.
+                    if (logger.isDebugEnabled()) {
+                               logger.debug("SQL Exception closing connection: " 
+                                               + sqle.getLocalizedMessage());
+                    }
+                } catch (Exception e) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Exception closing connection", e);
+                    }
+                }
+               }
         }
     }
 
index bf22acb74fab046cbad1a180522f5b49916617f5..f8b3ee2380ea61efc0f67df3e659839c5cb89362 100644 (file)
@@ -31,5 +31,6 @@ public class ReportConstants {
 
     public final static String NUXEO_DOCTYPE = "Report";
     public final static String NUXEO_SCHEMA_NAME = "report";
+    public final static String DB_COMMON_PART_TABLE_NAME = "reports_common";
     public final static String NUXEO_DC_TITLE = "CollectionSpace-Report";
 }
diff --git a/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportPostInitHandler.java b/services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportPostInitHandler.java
new file mode 100644 (file)
index 0000000..9945742
--- /dev/null
@@ -0,0 +1,123 @@
+/**\r
+ *  This document is a part of the source code and related artifacts\r
+ *  for CollectionSpace, an open source collections management system\r
+ *  for museums and related institutions:\r
+\r
+ *  http://www.collectionspace.org\r
+ *  http://wiki.collectionspace.org\r
+\r
+ *  Copyright 2009 University of California at Berkeley\r
+\r
+ *  Licensed under the Educational Community License (ECL), Version 2.0.\r
+ *  You may not use this file except in compliance with this License.\r
+\r
+ *  You may obtain a copy of the ECL 2.0 License at\r
+\r
+ *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
+ */\r
+package org.collectionspace.services.report.nuxeo;\r
+\r
+import java.sql.Connection;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.sql.Statement;\r
+import java.util.List;\r
+\r
+import org.collectionspace.services.common.api.Tools;\r
+import org.collectionspace.services.common.service.ServiceBindingType;\r
+import org.collectionspace.services.common.init.IInitHandler;\r
+import org.collectionspace.services.common.init.InitHandler;\r
+import org.collectionspace.services.common.service.InitHandler.Params.Field;\r
+import org.collectionspace.services.common.service.InitHandler.Params.Property;\r
+import org.collectionspace.services.common.storage.DatabaseProductType;\r
+import org.collectionspace.services.common.storage.JDBCTools;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * ReportPostInitHandler, post-init action to add grant reader access to DB\r
+ * \r
+ * In the configuration file, looks for a single Field declaration \r
+ * with a param value that has the name of the reader account/role.\r
+ * If not specified, it will assume 'reader'; \r
+ * \r
+ * $LastChangedRevision: 5103 $\r
+ * $LastChangedDate: 2011-06-23 16:50:06 -0700 (Thu, 23 Jun 2011) $\r
+ */\r
+public class ReportPostInitHandler extends InitHandler implements IInitHandler {\r
+\r
+    final Logger logger = LoggerFactory.getLogger(ReportPostInitHandler.class);\r
+    public static final String READ_ROLE_NAME_KEY = "readerRoleName";\r
+    private String readerRoleName = "reader";\r
+\r
+    /** See the class javadoc for this class: it shows the syntax supported in the configuration params.\r
+     */\r
+    @Override\r
+    public void onRepositoryInitialized(ServiceBindingType sbt, List<Field> fields, \r
+                       List<Property> properties) throws Exception {\r
+        //Check for existing privileges, and if not there, grant them\r
+       for(Property prop:properties) {\r
+               if(READ_ROLE_NAME_KEY.equals(prop.getKey())) {\r
+                   String value = prop.getValue();\r
+                   if(Tools.notEmpty(value) && !readerRoleName.equals(value)){\r
+                       readerRoleName = value;\r
+                       logger.debug("ReportPostInitHandler: overriding readerRoleName to use: "\r
+                               + value);\r
+                   }\r
+               }\r
+        }\r
+        Connection conn = null;\r
+        Statement stmt = null;\r
+        String sql = "";\r
+        try {\r
+            DatabaseProductType databaseProductType = JDBCTools.getDatabaseProductType();\r
+            if (databaseProductType == DatabaseProductType.MYSQL) {\r
+               // Nothing to do: MYSQL already does wildcard grants in init_db.sql\r
+            } else if(databaseProductType != DatabaseProductType.POSTGRESQL) {\r
+                throw new Exception("Unrecognized database system " + databaseProductType);\r
+            } else {\r
+                boolean hasRights = false;\r
+               // Check for rights on report_common, and infer rights from that\r
+               sql = "SELECT has_table_privilege('"+readerRoleName\r
+                       +"', '"+ReportConstants.DB_COMMON_PART_TABLE_NAME+"', 'SELECT')";\r
+                conn = JDBCTools.getConnection(JDBCTools.NUXEO_REPOSITORY_NAME);\r
+                stmt = conn.createStatement();\r
+                ResultSet rs = stmt.executeQuery(sql);\r
+                if(rs.next()) {\r
+                       hasRights = rs.getBoolean(1);\r
+                }\r
+                rs.close();\r
+                if(!hasRights) {\r
+                       sql = "REVOKE SELECT ON ALL TABLES IN SCHEMA public FROM "+readerRoleName;\r
+                    stmt.execute(sql);\r
+                       sql = "GRANT SELECT ON ALL TABLES IN SCHEMA public TO "+readerRoleName;\r
+                    stmt.execute(sql);\r
+                }\r
+            }\r
+            \r
+        } catch (SQLException sqle) {\r
+            SQLException tempException = sqle;\r
+            while (null != tempException) {       // SQLExceptions can be chained. Loop to log all.\r
+                logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
+                tempException = tempException.getNextException();\r
+            }\r
+            logger.debug("ReportPostInitHandler: SQL problem in executeQuery: ", sqle);\r
+        } catch (Throwable e) {\r
+            logger.debug("ReportPostInitHandler: problem checking/adding grant for reader: "+readerRoleName+") SQL: "+sql+" ERROR: "+e);\r
+        } finally {\r
+            try {\r
+                if (conn != null) {\r
+                    conn.close();\r
+                }\r
+                if (stmt != null) {\r
+                    stmt.close();\r
+                }\r
+            } catch (SQLException sqle) {\r
+                logger.debug("SQL Exception closing statement/connection in executeQuery: " + sqle.getLocalizedMessage());\r
+            }\r
+        }\r
+    }\r
+    \r
+\r
+}\r