]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
0a179a0781f9f74118ea33999b18340ff9b75715
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.report.nuxeo;
25
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileOutputStream;
30 import java.io.InputStream;
31 import java.nio.file.Files;
32 import java.sql.Connection;
33 import java.sql.SQLException;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37
38 import javax.ws.rs.core.MediaType;
39 import javax.naming.NamingException;
40 import javax.ws.rs.core.Response;
41
42 import net.sf.jasperreports.engine.JRException;
43 import net.sf.jasperreports.engine.JRExporter;
44 import net.sf.jasperreports.engine.JRExporterParameter;
45 import net.sf.jasperreports.engine.JRParameter;
46 import net.sf.jasperreports.engine.JasperCompileManager;
47 import net.sf.jasperreports.engine.JasperFillManager;
48 import net.sf.jasperreports.engine.JasperPrint;
49 import net.sf.jasperreports.engine.export.JRCsvExporter;
50 import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
51 import net.sf.jasperreports.engine.export.JRHtmlExporter;
52 import net.sf.jasperreports.engine.export.JRPdfExporter;
53 import net.sf.jasperreports.engine.export.JRXmlExporter;
54 import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
55 import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
56 import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
57
58 import org.collectionspace.authentication.AuthN;
59 import org.collectionspace.services.ReportJAXBSchema;
60 import org.collectionspace.services.account.AccountResource;
61 import org.collectionspace.services.authorization.AuthZ;
62 import org.collectionspace.services.authorization.CSpaceResource;
63 import org.collectionspace.services.authorization.PermissionException;
64 import org.collectionspace.services.authorization.URIResourceImpl;
65 import org.collectionspace.services.authorization.perms.ActionType;
66 import org.collectionspace.services.report.ResourceActionGroup;
67 import org.collectionspace.services.report.ResourceActionGroupList;
68 import org.collectionspace.services.report.ReportsCommon.ForRoles;
69 import org.collectionspace.services.report.MIMEType;
70 import org.collectionspace.services.report.MIMETypeItemType;
71 import org.collectionspace.services.report.ReportsCommon;
72 import org.collectionspace.services.report.ReportsOuputMimeList;
73 import org.collectionspace.services.client.PoxPayloadIn;
74 import org.collectionspace.services.client.PoxPayloadOut;
75 import org.collectionspace.services.client.ReportClient;
76 import org.collectionspace.services.common.CSWebApplicationException;
77 import org.collectionspace.services.common.ServiceMain;
78 import org.collectionspace.services.common.api.JEEServerDeployment;
79 import org.collectionspace.services.common.api.FileTools;
80 import org.collectionspace.services.common.api.Tools;
81 import org.collectionspace.services.common.authorization_mgt.ActionGroup;
82 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
83 import org.collectionspace.services.common.context.ServiceBindingUtils;
84 import org.collectionspace.services.common.context.ServiceContext;
85 import org.collectionspace.services.common.document.BadRequestException;
86 import org.collectionspace.services.common.document.DocumentException;
87 import org.collectionspace.services.common.document.DocumentWrapper;
88 import org.collectionspace.services.common.invocable.Invocable;
89 import org.collectionspace.services.common.invocable.InvocationContext;
90 import org.collectionspace.services.common.storage.JDBCTools;
91 import org.collectionspace.services.config.service.ServiceBindingType;
92 import org.collectionspace.services.config.types.PropertyItemType;
93 import org.collectionspace.services.jaxb.InvocableJAXBSchema;
94 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
95 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
96 import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
97 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
98
99 import org.jfree.util.Log;
100
101 import org.nuxeo.ecm.core.api.model.PropertyException;
102 import org.nuxeo.ecm.core.api.DocumentModel;
103
104 import org.slf4j.Logger;
105 import org.slf4j.LoggerFactory;
106
107 /**
108  * ReportDocumentModelHandler
109  *
110  * $LastChangedRevision: $
111  * $LastChangedDate: $
112  */
113 public class ReportDocumentModelHandler extends NuxeoDocumentModelHandler<ReportsCommon> {
114     private final Logger logger = LoggerFactory.getLogger(ReportDocumentModelHandler.class);
115     private static String REPORTS_FOLDER = "reports";
116     private static String CSID_LIST_SEPARATOR = ",";
117     
118     private static String REPORTS_STD_CSID_PARAM = "csid";
119     private static String REPORTS_STD_GROUPCSID_PARAM = "groupcsid";
120     private static String REPORTS_STD_CSIDLIST_PARAM = "csidlist";
121     private static String REPORTS_STD_TENANTID_PARAM = "tenantid";
122     
123     //
124     // Map the MIME types from the service bindings to our payload output
125     //
126     public ReportsOuputMimeList getSupportMIMETypes(
127                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
128         //
129         // Create a new payload response instance and initialize it
130         //
131         ReportsOuputMimeList result = new ReportsOuputMimeList();
132         MIMEType resultMIMEType = result.getMIMETypeList();
133         if (resultMIMEType == null) {
134                 result.setMIMETypeList(resultMIMEType = new MIMEType());
135         }
136         List<MIMETypeItemType> resultMIMETypeItemList = resultMIMEType.getMIMEType();
137         
138         //
139         // Read the MIME type values from the service bindings and put into our response payload
140         //
141         TenantBindingConfigReaderImpl tReader =
142                 ServiceMain.getInstance().getTenantBindingConfigReader();
143         ServiceBindingType reportServiceBinding = tReader.getServiceBinding(ctx.getTenantId(), ctx.getServiceName());
144         List<PropertyItemType> bindingsMIMETypeList = ServiceBindingUtils.getPropertyValueList(reportServiceBinding, ServiceBindingUtils.OUTPUT_MIME_PROP);
145         
146         if (bindingsMIMETypeList != null) {
147                 for (PropertyItemType bindingItemMimeType : bindingsMIMETypeList) {
148                         MIMETypeItemType resultMimeTypeItem = new MIMETypeItemType();
149                         String displayName = bindingItemMimeType.getDisplayName();
150                         if (displayName != null && displayName.trim().isEmpty() == false) {
151                         resultMimeTypeItem.setKey(displayName);
152                         } else {
153                         resultMimeTypeItem.setKey(bindingItemMimeType.getValue());
154                         }
155                         resultMimeTypeItem.setValue(bindingItemMimeType.getValue());
156                         resultMIMETypeItemList.add(resultMimeTypeItem);
157                 }
158         }
159
160         return result;
161     }
162     
163         public InputStream invokeReport(
164                         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
165                         String csid,
166                         ReportsCommon reportsCommon,
167                         InvocationContext invContext,
168                         StringBuffer outMimeType,
169                         StringBuffer outReportFileName) throws Exception {
170                 CoreSessionInterface repoSession = null;
171                 boolean releaseRepoSession = false;
172                 
173                 // Ensure the current user has permission to run this report
174                 if (isAuthoritzed(reportsCommon) == false) {
175                         String msg = String.format("Report Resource: The user '%s' is not authorized to run the report '%s' CSID='%s'", 
176                                         AuthN.get().getUserId(), reportsCommon.getName(), csid);
177                         throw new PermissionException(msg);
178                 }
179
180                 String invocationMode = invContext.getMode();
181                 String modeProperty = null;
182                 HashMap<String, Object> params = new HashMap<String, Object>();
183                 params.put(REPORTS_STD_TENANTID_PARAM, ctx.getTenantId());
184                 boolean checkDocType = true;
185                 
186                 // Note we set before we put in the default ones, so they cannot override tenant or CSID.
187                 setParamsFromContext(params, invContext);
188                 
189                 if (Invocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
190                         modeProperty = InvocableJAXBSchema.SUPPORTS_SINGLE_DOC;
191                 params.put(REPORTS_STD_CSID_PARAM, invContext.getSingleCSID());
192                 } else if (Invocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
193                         modeProperty = InvocableJAXBSchema.SUPPORTS_DOC_LIST;
194                         List<String> csids = null;
195                         InvocationContext.ListCSIDs listThing = invContext.getListCSIDs();
196                                 if (listThing!=null) {
197                                         csids = listThing.getCsid();
198                                 }
199                                 if (csids==null||csids.isEmpty()){
200                                 throw new BadRequestException(
201                                                 "ReportResource: Report invoked in list mode, with no csids in list." );
202                                 }
203                                 StringBuilder sb = new StringBuilder();
204                                 boolean first = true;
205                                 for(String csidItem : csids) {
206                                         if(first)
207                                                 first = false;
208                                         else
209                                                 sb.append(CSID_LIST_SEPARATOR);
210                                         sb.append(csidItem);
211                                 }
212                 params.put(REPORTS_STD_CSIDLIST_PARAM, sb.toString());
213                 } else if(Invocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
214                         modeProperty = InvocableJAXBSchema.SUPPORTS_GROUP;
215                 params.put(REPORTS_STD_GROUPCSID_PARAM, invContext.getGroupCSID());
216                 } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
217                         modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
218                         checkDocType = false;
219                 } else {
220                         throw new BadRequestException("ReportResource: unknown Invocation Mode: "
221                                 +invocationMode);
222                 }
223                 
224                 NuxeoRepositoryClientImpl repoClient = (NuxeoRepositoryClientImpl)this.getRepositoryClient(ctx);
225                 repoSession = this.getRepositorySession();
226                 if (repoSession == null) {
227                         repoSession = repoClient.getRepositorySession(ctx);
228                         releaseRepoSession = true;
229                 }
230
231                 // Get properties from the report docModel, and release the session
232                 String reportFileNameProperty;
233                 try {
234                         DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, csid);
235                         DocumentModel docModel = wrapper.getWrappedObject();
236                         Boolean supports = (Boolean) NuxeoUtils.getProperyValue(docModel, modeProperty); //docModel.getPropertyValue(modeProperty);
237                         if(supports == null || !supports) {
238                                 throw new BadRequestException(
239                                                 "ReportResource: This Report does not support Invocation Mode: "
240                                         +invocationMode);
241                         }
242                 if (checkDocType) {
243                         List<String> forDocTypeList = 
244                                 (List<String>) NuxeoUtils.getProperyValue(docModel, InvocableJAXBSchema.FOR_DOC_TYPES); //docModel.getPropertyValue(InvocableJAXBSchema.FOR_DOC_TYPES);
245                         if (forDocTypeList==null || !forDocTypeList.contains(invContext.getDocType())) {
246                                 throw new BadRequestException(
247                                                 "ReportResource: Invoked with unsupported document type: "
248                                                 +invContext.getDocType());
249                         }
250                 }
251                 reportFileNameProperty = (String) NuxeoUtils.getProperyValue(docModel, ReportJAXBSchema.FILENAME); //docModel.getPropertyValue(ReportJAXBSchema.FILENAME)); // Set the outgoing param with the report file name
252                         //
253                 // If the invocation context contains a MIME type then use it.  Otherwise, look in the report resource.  If no MIME type in the report resource,
254                 // use the default MIME type.
255                 //
256                 if (!Tools.isEmpty(invContext.getOutputMIME())) {
257                         outMimeType.append(invContext.getOutputMIME());
258                 }
259                 if (outMimeType == null || Tools.isEmpty(outMimeType.toString())) {
260                 String reportOutputMime = (String) NuxeoUtils.getProperyValue(docModel, ReportJAXBSchema.OUTPUT_MIME); //docModel.getPropertyValue(ReportJAXBSchema.OUTPUT_MIME);
261                         if (!Tools.isEmpty(reportOutputMime)) {
262                                 outMimeType.append(reportOutputMime);
263                         } else {
264                                 outMimeType.append(ReportClient.DEFAULT_REPORT_OUTPUT_MIME);
265                         }
266                 }
267                 } catch (PropertyException pe) {
268                         if (logger.isDebugEnabled()) {
269                                 logger.debug("Property exception getting report values: ", pe);
270                         }
271                         throw pe;
272                 } catch (DocumentException de) {
273                         if (logger.isDebugEnabled()) {
274                                 logger.debug("Problem getting report report: ", de);
275                         }
276                         throw de;
277                 } catch (Exception e) {
278                         if (logger.isDebugEnabled()) {
279                                 logger.debug("Caught exception ", e);
280                         }
281                         throw new DocumentException(e);
282                 } finally {
283                         if (releaseRepoSession && repoSession != null) {
284                                 repoClient.releaseRepositorySession(ctx, repoSession);
285                         }
286                 }
287                 
288         return buildReportResult(csid, params, reportFileNameProperty, outMimeType.toString(), outReportFileName);
289         }
290         
291         private void setParamsFromContext(Map<String, Object> params, InvocationContext invContext) {
292                 InvocationContext.Params icParams = invContext.getParams();
293                 if(icParams!= null) {
294                         List<InvocationContext.Params.Param> icParamList = icParams.getParam();
295                         if(icParamList != null) {
296                                 for(InvocationContext.Params.Param param:icParamList) {
297                                         String key = param.getKey();
298                                         String value = param.getValue();
299                                         if(!Tools.isEmpty(key) && !Tools.isEmpty(value)) {
300                                                 params.put(key, value);
301                                         }
302                                 }
303                         }
304                 }
305                 
306         }
307
308     private InputStream buildReportResult(String reportCSID, 
309                 HashMap<String, Object> params, String reportFileName, String outputMimeType, StringBuffer outReportFileName)
310                                 throws Exception {
311                 Connection conn = null;
312                 InputStream result = null;
313                 
314         try {
315                 String fileNameBase = Tools.getFilenameBase(reportFileName);
316                 String compiledReportFilename = fileNameBase+ReportClient.COMPILED_REPORT_EXTENSION;
317                 String reportDescriptionFilename = fileNameBase+ReportClient.REPORT_DECSRIPTION_EXTENSION;
318                 
319                         String basePath = ServiceMain.getInstance().getServerRootDir() +
320                                                                 File.separator + JEEServerDeployment.CSPACE_DIR_NAME + 
321                                                                 File.separator + REPORTS_FOLDER +
322                                                                 // File.separator + tenantName +
323                                                                 File.separator; // + reportFileName;
324                         
325                         String compiledFilePath = basePath+compiledReportFilename; 
326                         File f = new File(compiledFilePath);
327                         if(!f.exists()) { // Need to compile the file
328                                 // First verify that there is a source file.
329                                 String sourceFilePath = basePath+reportDescriptionFilename; 
330                                 File f2 = new File(sourceFilePath);
331                                 if(!f2.exists()) { // Missing source file - error!
332                                         logger.error("Report for csid={} is missing the specified source file: {}",
333                                                                         reportCSID, sourceFilePath);
334                                         throw new RuntimeException("Report is missing the specified source file!");
335                                 }
336                 logger.info("Report for csid={} is not compiled. Compiling first, and saving to: {}",
337                                 reportCSID, compiledFilePath);
338                 JasperCompileManager.compileReportToFile(sourceFilePath, compiledFilePath);
339                         }                               
340                                 
341                         conn = getConnection();
342         
343             if (logger.isTraceEnabled()) {
344                 logger.trace("ReportResource for csid=" + reportCSID
345                                 +" output as "+outputMimeType+" using report file: "+compiledFilePath);
346             }
347                         FileInputStream fileStream = new FileInputStream(compiledFilePath);
348         
349                         // export report to pdf and build a response with the bytes
350                         //JasperExportManager.exportReportToPdf(jasperprint);
351                         
352                         JRExporter exporter = null;
353                         // Strip extension from report filename.
354                         String outputFilename = reportFileName;
355                         // Strip extension from report filename.
356                         int idx = outputFilename.lastIndexOf("."); 
357                         if(idx>0)
358                                 outputFilename = outputFilename.substring(0, idx);
359                         // Strip any sub-dir from report filename.
360                         idx = outputFilename.lastIndexOf(File.separator); 
361                         if(idx>0)
362                                 outputFilename = outputFilename.substring(idx+1);
363                         if(outputMimeType.equals(MediaType.APPLICATION_XML)) {
364                                 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
365                                 exporter = new JRXmlExporter();
366                                 outputFilename = outputFilename+".xml";
367                         } else if(outputMimeType.equals(MediaType.TEXT_HTML)) {
368                                 exporter = new JRHtmlExporter();
369                                 outputFilename = outputFilename+".html";
370                         } else if(outputMimeType.equals(ReportClient.PDF_MIME_TYPE)) {
371                                 exporter = new JRPdfExporter();
372                                 outputFilename = outputFilename+".pdf";
373                         } else if(outputMimeType.equals(ReportClient.CSV_MIME_TYPE)) {
374                                 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
375                                 exporter = new JRCsvExporter();
376                                 exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ",");
377                                 outputFilename = outputFilename+".csv";
378                         } else if(outputMimeType.equals(ReportClient.TSV_MIME_TYPE)) {
379                                 params.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);
380                                 exporter = new JRCsvExporter();
381                                 exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, "\t");
382                                 outputFilename = outputFilename+".csv";
383                         } else if(outputMimeType.equals(ReportClient.MSWORD_MIME_TYPE)  // Understand msword as docx
384                                         || outputMimeType.equals(ReportClient.OPEN_DOCX_MIME_TYPE)) {
385                                 exporter = new JRDocxExporter();
386                                 outputFilename = outputFilename+".docx";
387                         } else if(outputMimeType.equals(ReportClient.MSEXCEL_MIME_TYPE) // Understand msexcel as xlsx
388                                         || outputMimeType.equals(ReportClient.OPEN_XLSX_MIME_TYPE)) {
389                                 exporter = new JRXlsxExporter();
390                                 outputFilename = outputFilename+".xlsx";
391                         } else if(outputMimeType.equals(ReportClient.MSPPT_MIME_TYPE)   // Understand msppt as xlsx
392                                         || outputMimeType.equals(ReportClient.OPEN_PPTX_MIME_TYPE)) {
393                                 exporter = new JRPptxExporter();
394                                 outputFilename = outputFilename+".pptx";
395                         } else {
396                                 logger.error("Reporting: unsupported output MIME type - defaulting to PDF");
397                                 exporter = new JRPdfExporter();
398                                 outputFilename = outputFilename+"-default-to.pdf";
399                         }
400                         outReportFileName.append(outputFilename); // Set the out going param to the report's final file name
401                         // FIXME: Logging temporarily set to INFO level for CSPACE-5766;
402                         // can change to TRACE or DEBUG level as warranted thereafter
403                         if (logger.isInfoEnabled()) {
404                             logger.info(FileTools.getJavaTmpDirInfo());
405                         }
406                         // fill the report
407                         JasperPrint jasperPrint = JasperFillManager.fillReport(fileStream, params,conn);
408                                 
409                         // Report will be to a temporary file.
410                         File tempOutputFile = Files.createTempFile("report-", null).toFile();
411                         FileOutputStream tempOutputStream = new FileOutputStream(tempOutputFile);                       
412                         exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
413                         exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, tempOutputStream);
414                         exporter.exportReport();
415                         tempOutputStream.close();
416                         
417                         result = new FileInputStream(tempOutputFile);
418                 return result;
419         } catch (SQLException sqle) {
420             // SQLExceptions can be chained. We have at least one exception, so
421             // set up a loop to make sure we let the user know about all of them
422             // if there happens to be more than one.
423             if (logger.isDebugEnabled()) {
424                     SQLException tempException = sqle;
425                     while (null != tempException) {
426                                 logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
427         
428                         // loop to the next exception
429                         tempException = tempException.getNextException();
430                     }
431             }
432             Response response = Response.status(
433                     Response.Status.INTERNAL_SERVER_ERROR).entity(
434                                 "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
435             throw new CSWebApplicationException(sqle, response);
436         } catch (JRException jre) {
437             if (logger.isDebugEnabled()) {
438                 logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
439             }
440             Response response = Response.status(
441                     Response.Status.INTERNAL_SERVER_ERROR).entity(
442                                 "Invoke failed (Jasper problem) on Report csid=" + reportCSID).type("text/plain").build();
443             throw new CSWebApplicationException(jre, response);
444         } catch (FileNotFoundException fnfe) {
445             if (logger.isDebugEnabled()) {
446                 logger.debug("FileNotFoundException: " + fnfe.getLocalizedMessage());
447             }
448             Response response = Response.status(
449                     Response.Status.INTERNAL_SERVER_ERROR).entity(
450                                 "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
451             throw new CSWebApplicationException(fnfe, response);
452                 } finally {
453                 if (conn!=null) {
454                         try {
455                                 conn.close();
456                 } catch (SQLException sqle) {
457                     // SQLExceptions can be chained. We have at least one exception, so
458                     // set up a loop to make sure we let the user know about all of them
459                     // if there happens to be more than one.
460                     if (logger.isDebugEnabled()) {
461                                 logger.debug("SQL Exception closing connection: " 
462                                                 + sqle.getLocalizedMessage());
463                     }
464                 } catch (Exception e) {
465                     if (logger.isDebugEnabled()) {
466                         logger.debug("Exception closing connection", e);
467                     }
468                 }
469                 }
470         }
471     }
472
473     private Connection getConnection() throws NamingException, SQLException {
474         Connection result = null;
475         
476         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
477         try {
478                 String repositoryName = ctx.getRepositoryName();
479                 if (repositoryName != null && repositoryName.trim().isEmpty() == false) {
480                         String cspaceInstanceId = ServiceMain.getInstance().getCspaceInstanceId();
481                         String databaseName = JDBCTools.getDatabaseName(repositoryName, cspaceInstanceId);
482                         result = JDBCTools.getConnection(JDBCTools.NUXEO_READER_DATASOURCE_NAME, databaseName);
483                 }
484                 } catch (Exception e) {
485                         Log.error(e);
486                         throw new NamingException();
487                 }
488         
489         return result;
490     }
491
492         /**
493          * Check to see if the current user is authorized to run/invoke this report.  If the report
494          * did not specify any permissions, we assume that the current user is authorized to run the report.
495          * @param reportsCommon
496          * @return
497          */
498         protected boolean isAuthoritzedWithPermissions(ReportsCommon reportsCommon) {
499                 boolean result = true;
500                 
501                 ResourceActionGroupList resourceActionGroupList = reportsCommon.getResourceActionGroupList();
502                 if (resourceActionGroupList != null) {
503                         String tenantId = AuthN.get().getCurrentTenantId();
504                         for (ResourceActionGroup resourceActionGroup: resourceActionGroupList.getResourceActionGroup()) {
505                                 String resourceName = resourceActionGroup.getResourceName();
506                                 ActionGroup actionGroup = ActionGroup.creatActionGroup(resourceActionGroup.getActionGroup());
507                                 for (ActionType actionType: actionGroup.getActions()) {
508                                         CSpaceResource res = new URIResourceImpl(tenantId, resourceName, AuthZ.getMethod(actionType));
509                                         if (AuthZ.get().isAccessAllowed(res) == false) {
510                                                 return false;
511                                         }
512                                 }
513                         }
514                 }
515                 
516                 return result;
517         }
518
519         /**
520          * Returns true if we found any required permissions.
521          * 
522          * @param reportCommon
523          * @return
524          */
525         private boolean hasRequiredPermissions(ReportsCommon reportCommon) {
526                 boolean result = false;
527                 
528                 try {
529                         result = reportCommon.getResourceActionGroupList().getResourceActionGroup().size() > 0;
530                 } catch (NullPointerException e) {
531                         // ignore exception, we're just testing to see if we have any list elements
532                 }
533                 
534                 return result;
535         }
536         
537         /**
538          * Returns true if we found any required roles.
539          * 
540          * @param reportCommon
541          * @return
542          */
543         private boolean hasRequiredRoles(ReportsCommon reportCommon) {
544                 boolean result = false;
545                 
546                 try {
547                         result = reportCommon.getForRoles().getRoleDisplayName().size() > 0;
548                 } catch (NullPointerException e) {
549                         // ignore exception, we're just testing to see if we have any list elements
550                 }
551                 
552                 return result;
553         }
554     
555         /**
556          * The current user is authorized to run the report if:
557          *      1. No permissions or roles are specified in the report
558          *  2. No roles are specified, but permissions are specified and the current user has those permissions
559          *  3. Roles are specified and the current user is a member of at least one of the roles.
560          * 
561          * @param reportsCommon
562          * @return
563          */
564         protected boolean isAuthoritzed(ReportsCommon reportsCommon) {
565                 boolean result = true;
566                 
567                 if (hasRequiredRoles(reportsCommon)) { 
568                         result = isAuthorizedWithRoles(reportsCommon);
569                 } else if (hasRequiredPermissions(reportsCommon)) {
570                         result = isAuthoritzedWithPermissions(reportsCommon);
571                 }
572                                 
573                 return result;
574         }
575         
576         protected boolean isAuthorizedWithRoles(ReportsCommon reportCommon) {
577                 boolean result = false;
578                 
579                 ForRoles forRolesList = reportCommon.getForRoles();
580                 if (forRolesList != null) {
581                         AccountResource accountResource = new AccountResource();
582                         List<String> roleDisplayNameList = accountResource.getAccountRoles(AuthN.get().getUserId(), AuthN.get().getCurrentTenantId());
583                         for (String target : forRolesList.getRoleDisplayName()) {
584                                 if (Tools.listContainsIgnoreCase(roleDisplayNameList, target)) {
585                                         result = true;
586                                         break;
587                                 }
588                         }
589                 }
590                 
591                 return result;
592         }
593
594 }
595