<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">
}\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
return null;\r
}\r
}\r
- }\r
+ } */\r
\r
public static int executeUpdate(String repoName, String sql) throws Exception {\r
Connection conn = null;\r
</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
--- /dev/null
+<?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>
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;
@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
+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);
+ }
+ }
+ }
}
}
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";
}
--- /dev/null
+/**\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