001/* 002 * Kuali Coeus, a comprehensive research administration system for higher education. 003 * 004 * Copyright 2005-2015 Kuali, Inc. 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Affero General Public License as 008 * published by the Free Software Foundation, either version 3 of the 009 * License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU Affero General Public License for more details. 015 * 016 * You should have received a copy of the GNU Affero General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.kuali.coeus.s2sgen.impl.print; 020 021import gov.grants.apply.system.metaGrantApplication.GrantApplicationDocument; 022import gov.grants.apply.system.metaGrantApplication.GrantApplicationDocument.GrantApplication.Forms; 023import org.apache.commons.lang3.StringUtils; 024import org.apache.xmlbeans.XmlCursor; 025import org.apache.xmlbeans.XmlException; 026import org.apache.xmlbeans.XmlObject; 027import org.apache.xpath.XPathAPI; 028import org.kuali.coeus.propdev.api.core.DevelopmentProposalContract; 029import org.kuali.coeus.propdev.api.person.attachment.ProposalPersonBiographyContract; 030import org.kuali.coeus.propdev.api.s2s.*; 031import org.kuali.coeus.s2sgen.api.core.AuditError; 032import org.kuali.coeus.s2sgen.api.core.S2SException; 033import org.kuali.coeus.s2sgen.api.generate.FormMappingInfo; 034import org.kuali.coeus.s2sgen.api.generate.FormMappingService; 035import org.kuali.coeus.s2sgen.api.print.FormPrintService; 036import org.kuali.coeus.s2sgen.api.print.FormPrintResult; 037import org.kuali.coeus.s2sgen.impl.generate.S2SFormGenerator; 038import org.kuali.coeus.s2sgen.impl.util.ClassLoaderUtils; 039import org.kuali.coeus.s2sgen.impl.util.XPathExecutor; 040import org.kuali.coeus.s2sgen.impl.datetime.S2SDateTimeService; 041import org.kuali.coeus.s2sgen.impl.generate.S2SFormGeneratorRetrievalService; 042import org.kuali.coeus.s2sgen.impl.validate.S2SValidatorService; 043import org.kuali.coeus.propdev.api.core.ProposalDevelopmentDocumentContract; 044import org.kuali.coeus.sys.api.model.KcFile; 045import org.kuali.coeus.s2sgen.api.core.ConfigurationConstants; 046import org.kuali.coeus.propdev.api.attachment.NarrativeContract; 047import org.kuali.coeus.propdev.api.attachment.NarrativeService; 048import org.kuali.coeus.s2sgen.api.generate.AttachmentData; 049import org.slf4j.Logger; 050import org.slf4j.LoggerFactory; 051import org.springframework.beans.factory.annotation.Autowired; 052import org.springframework.beans.factory.annotation.Qualifier; 053import org.springframework.core.io.DefaultResourceLoader; 054import org.springframework.core.io.Resource; 055import org.springframework.stereotype.Component; 056import org.w3c.dom.Element; 057 058import javax.xml.transform.Source; 059import javax.xml.transform.stream.StreamSource; 060import java.io.*; 061import java.util.*; 062import java.util.zip.ZipEntry; 063import java.util.zip.ZipOutputStream; 064 065/** 066 * This class is implementation of PrintService. It provides the functionality 067 * to generate PDF for all forms along with their attachments 068 */ 069@Component("formPrintService") 070public class FormPrintServiceImpl implements FormPrintService { 071 private static final Logger LOG = LoggerFactory.getLogger(FormPrintServiceImpl.class); 072 private static final String PDF_FILE_EXTENSION = ".pdf"; 073 074 @Autowired 075 @Qualifier("s2sApplicationService") 076 private S2sApplicationService s2sApplicationService; 077 078 @Autowired 079 @Qualifier("s2SFormGeneratorRetrievalService") 080 private S2SFormGeneratorRetrievalService s2SFormGeneratorService; 081 082 @Autowired 083 @Qualifier("s2SValidatorService") 084 private S2SValidatorService s2SValidatorService; 085 086 @Autowired 087 @Qualifier("s2SConfigurationService") 088 private S2SConfigurationService s2SConfigurationService; 089 090 @Autowired 091 @Qualifier("s2SDateTimeService") 092 private S2SDateTimeService s2SDateTimeService; 093 094 @Autowired 095 @Qualifier("narrativeService") 096 private NarrativeService narrativeService; 097 098 @Autowired 099 @Qualifier("s2SPrintingService") 100 private S2SPrintingService s2SPrintingService; 101 102 @Autowired 103 @Qualifier("formMappingService") 104 private FormMappingService formMappingService; 105 106 @Autowired 107 @Qualifier("userAttachedFormService") 108 private UserAttachedFormService userAttachedFormService; 109 110 /** 111 * 112 * This method is used for the printing of forms in PDF format. It generates 113 * PDF forms and puts it into {@link KcFile} 114 * 115 * @param pdDoc (ProposalDevelopmentDocumentContract) 116 * @return {@link KcFile} which contains all information 117 * related to the generated PDF 118 * @throws 119 * @throws S2SException 120 * 121 */ 122 @Override 123 public FormPrintResult printForm(Object pdDoc) throws S2SException { 124 125 if (pdDoc == null) { 126 throw new IllegalArgumentException("pdDoc is null"); 127 } 128 129 ProposalDevelopmentDocumentContract pdDocContract = (ProposalDevelopmentDocumentContract) pdDoc; 130 131 PrintableResult pResult; 132 S2sAppSubmissionContract s2sAppSubmission = getLatestS2SAppSubmission(pdDocContract); 133 if (s2sAppSubmission != null 134 && s2sAppSubmission.getGgTrackingId() != null) { 135 pResult = getSubmittedPDFStream(pdDocContract); 136 } else { 137 pResult = getPDFStream(pdDocContract); 138 } 139 if(pdDocContract.getDevelopmentProposal().getGrantsGovSelectFlag()){ 140 FormPrintResult result = new FormPrintResult(); 141 result.setErrors(pResult.errors); 142 return result; 143 } 144 S2SFile attachmentDataSource = s2SPrintingService 145 .print(pResult.printables); 146 attachmentDataSource.setName(getFileNameForFormPrinting(pdDocContract)); 147 148 FormPrintResult result = new FormPrintResult(); 149 result.setFile(attachmentDataSource); 150 result.setErrors(pResult.errors); 151 return result; 152 } 153 154 protected void saveGrantsGovXml(ProposalDevelopmentDocumentContract pdDoc, boolean formEntryFlag,XmlObject formObject,List<AttachmentData> attachmentList,List<? extends S2sAppAttachmentsContract> attachmentLists) throws Exception{ 155 String loggingDirectory = s2SConfigurationService.getValueAsString(ConfigurationConstants.PRINT_XML_DIRECTORY); 156 String opportunityId = pdDoc.getDevelopmentProposal().getS2sOpportunity().getOpportunityId(); 157 String proposalnumber = pdDoc.getDevelopmentProposal().getProposalNumber(); 158 String exportDate = StringUtils.replaceChars((pdDoc.getDevelopmentProposal().getUpdateTimestamp().toString()), ":", "_"); 159 exportDate = StringUtils.replaceChars(exportDate, " ", "."); 160 161 File grantsGovXmlDirectoryFile = new File(loggingDirectory + opportunityId + "." + proposalnumber + "." + exportDate); 162 if (!grantsGovXmlDirectoryFile.exists() || formEntryFlag) { 163 grantsGovXmlDirectoryFile.mkdir(); 164 } 165 166 for (AttachmentData attachmentData : attachmentList) { 167 File attachmentFile = new File(grantsGovXmlDirectoryFile,"Attachments"); 168 attachmentFile.mkdir(); 169 File attachedFile = new File(attachmentFile,attachmentData.getFileName()); 170 try (FileOutputStream output = new FileOutputStream(attachedFile)) { 171 output.write(attachmentData.getContent()); 172 } 173 } 174 for (S2sAppAttachmentsContract attAppAttachments : attachmentLists) { 175 File attachmentFile = new File(grantsGovXmlDirectoryFile,"Attachments"); 176 attachmentFile.mkdir(); 177 KcFile ads = getAttributeContent(pdDoc,attAppAttachments.getContentId()); 178 File attachedFile = new File(attachmentFile,ads.getName()); 179 try (FileOutputStream output = new FileOutputStream(attachedFile)) { 180 output.write(getAttContent(pdDoc, attAppAttachments.getContentId())); 181 } 182 } 183 File xmlFile= new File(grantsGovXmlDirectoryFile,opportunityId + "." + proposalnumber + "." + exportDate+".xml"); 184 try (BufferedWriter out = new BufferedWriter(new FileWriter(xmlFile))) { 185 out.write(formObject.xmlText()); 186 } 187 188 try (FileOutputStream fileOutputStream = new FileOutputStream(grantsGovXmlDirectoryFile+".zip"); ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) { 189 addFolderToZip("", grantsGovXmlDirectoryFile.getPath(), zipOutputStream); 190 zipOutputStream.flush(); 191 } 192 193 } 194 195 protected void addFolderToZip(String path, String sourceFolder, ZipOutputStream zipOutputStream) throws Exception { 196 File proposalNumberfolder = new File(sourceFolder); 197 for (String fileName : proposalNumberfolder.list()) { 198 if (path.equals("")) { 199 addFileToZip(proposalNumberfolder.getName(), sourceFolder + "/" + fileName, zipOutputStream); 200 } else { 201 addFileToZip(path + "/" + proposalNumberfolder.getName(), sourceFolder + "/" + fileName, zipOutputStream); 202 } 203 } 204 } 205 206 protected void addFileToZip(String path, String sourceFile, ZipOutputStream zipOutputStream) throws Exception { 207 File attachmentFile = new File(sourceFile); 208 if (attachmentFile.isDirectory()) { 209 addFolderToZip(path, sourceFile, zipOutputStream); 210 } else { 211 byte[] buffer = new byte[1024]; 212 int length; 213 try (FileInputStream fileInputStream = new FileInputStream(attachmentFile)) { 214 zipOutputStream.putNextEntry(new ZipEntry(path + "/" + attachmentFile.getName())); 215 while ((length = fileInputStream.read(buffer)) > 0) { 216 zipOutputStream.write(buffer, 0, length); 217 } 218 } 219 } 220 } 221 protected String getFileNameForFormPrinting(ProposalDevelopmentDocumentContract pdDoc) { 222 StringBuilder fileName = new StringBuilder(); 223 fileName.append(pdDoc.getDocumentNumber()); 224 fileName.append(pdDoc.getDevelopmentProposal() 225 .getProgramAnnouncementNumber()); 226 fileName.append(PDF_FILE_EXTENSION); 227 return fileName.toString(); 228 } 229 230 /** 231 * 232 * This method is to write the submitted application data to a pdfStream 233 * 234 * @param pdDoc 235 * Proposal Development Document. 236 * @return ByteArrayOutputStream[] of the submitted application data. 237 * @throws S2SException 238 */ 239 protected PrintableResult getSubmittedPDFStream( 240 ProposalDevelopmentDocumentContract pdDoc) throws S2SException { 241 GrantApplicationDocument submittedDocument; 242 String frmXpath = null; 243 String frmAttXpath = null; 244 try { 245 S2sAppSubmissionContract s2sAppSubmission = getLatestS2SAppSubmission(pdDoc); 246 String submittedApplicationXml = findSubmittedXml(s2sAppSubmission); 247 String submittedApplication = s2SDateTimeService.removeTimezoneFactor(submittedApplicationXml); 248 submittedDocument = GrantApplicationDocument.Factory.parse(submittedApplication); 249 } catch (XmlException e) { 250 LOG.error(e.getMessage(), e); 251 throw new S2SException(e); 252 } 253 FormMappingInfo info = null; 254 DevelopmentProposalContract developmentProposal = pdDoc.getDevelopmentProposal(); 255 List<String> sortedNameSpaces = getSortedNameSpaces(developmentProposal.getProposalNumber(),developmentProposal.getS2sOppForms()); 256 boolean formEntryFlag = true; 257 List<S2SPrintable> formPrintables = new ArrayList<>(); 258 for (String namespace : sortedNameSpaces) { 259 XmlObject formFragment = null; 260 info = formMappingService.getFormInfo(namespace); 261 if(info==null) continue; 262 formFragment = getFormObject(submittedDocument, info); 263 frmXpath = "//*[namespace-uri(.) = '"+namespace+"']"; 264 frmAttXpath = "//*[namespace-uri(.) = '"+namespace+"']//*[local-name(.) = 'FileLocation' and namespace-uri(.) = 'http://apply.grants.gov/system/Attachments-V1.0']"; 265 266 byte[] formXmlBytes = formFragment.xmlText().getBytes(); 267 GenericPrintable formPrintable = new GenericPrintable(); 268 269 ArrayList<Source> templates = new ArrayList<Source>(); 270 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader()); 271 Resource resource = resourceLoader.getResource(info.getStyleSheet()); 272 273 Source xsltSource = null; 274 try { 275 xsltSource = new StreamSource(resource.getInputStream()); 276 } catch (IOException e) { 277 throw new S2SException(e); 278 } 279 templates.add(xsltSource); 280 formPrintable.setXSLTemplates(templates); 281 282 // Linkedhashmap is used to preserve the order of entry. 283 Map<String, byte[]> formXmlDataMap = new LinkedHashMap<String, byte[]>(); 284 formXmlDataMap.put(info.getFormName(), formXmlBytes); 285 formPrintable.setStreamMap(formXmlDataMap); 286 S2sApplicationContract s2sApplciation = s2sApplicationService.findS2sApplicationByProposalNumber(pdDoc.getDevelopmentProposal().getProposalNumber()); 287 List<? extends S2sAppAttachmentsContract> attachmentList = s2sApplciation.getS2sAppAttachmentList(); 288 289 Map<String, byte[]> formAttachments = new LinkedHashMap<String, byte[]>(); 290 291 try{ 292 XPathExecutor executer = new XPathExecutor(formFragment.toString()); 293 org.w3c.dom.Node d = executer.getNode(frmXpath); 294 org.w3c.dom.NodeList attList = XPathAPI.selectNodeList(d, frmAttXpath); 295 int attLen = attList.getLength(); 296 297 for(int i=0;i<attLen;i++){ 298 org.w3c.dom.Node attNode = attList.item(i); 299 String contentId = ((Element)attNode).getAttributeNS("http://apply.grants.gov/system/Attachments-V1.0","href"); 300 301 if (attachmentList != null && !attachmentList.isEmpty()) { 302 for (S2sAppAttachmentsContract attAppAttachments : attachmentList) { 303 if(attAppAttachments.getContentId().equals(contentId)){ 304 try (ByteArrayOutputStream attStream = new ByteArrayOutputStream()) { 305 attStream.write(getAttContent(pdDoc, 306 attAppAttachments.getContentId())); 307 } catch (IOException e) { 308 LOG.error(e.getMessage(), e); 309 throw new S2SException(e); 310 } 311 StringBuilder attachment = new StringBuilder(); 312 attachment.append(" ATT : "); 313 attachment.append(attAppAttachments.getContentId()); 314 formAttachments.put(attachment.toString(), 315 getAttContent(pdDoc, attAppAttachments 316 .getContentId())); 317 } 318 } 319 } 320 } 321 } catch (Exception e) { 322 LOG.error(e.getMessage(), e); 323 } 324 try { 325 if(developmentProposal.getGrantsGovSelectFlag()){ 326 List<AttachmentData> attachmentLists = new ArrayList<AttachmentData>(); 327 saveGrantsGovXml(pdDoc,formEntryFlag,formFragment,attachmentLists,attachmentList); 328 formEntryFlag = false; 329 } 330 } catch (Exception e) { 331 LOG.error(e.getMessage(), e); 332 } 333 formPrintable.setAttachments(formAttachments); 334 formPrintables.add(formPrintable); 335 } 336 PrintableResult result = new PrintableResult(); 337 result.printables = formPrintables; 338 return result; 339 } 340 341 protected String findSubmittedXml(S2sAppSubmissionContract appSubmission) { 342 S2sApplicationContract s2sApplication = s2sApplicationService.findS2sApplicationByProposalNumber(appSubmission.getProposalNumber()); 343 return s2sApplication.getApplication(); 344 } 345 346 347 348 /** 349 * This method is used to generate byte stream of forms 350 * 351 * @param pdDoc 352 * ProposalDevelopmentDocumentContract 353 * @return ByteArrayOutputStream[] PDF byte Array 354 * @throws S2SException 355 */ 356 protected PrintableResult getPDFStream(ProposalDevelopmentDocumentContract pdDoc) 357 throws S2SException { 358 359 List<AuditError> errors = new ArrayList<AuditError>(); 360 DevelopmentProposalContract developmentProposal = pdDoc 361 .getDevelopmentProposal(); 362 String proposalNumber = developmentProposal.getProposalNumber(); 363 List<String> sortedNameSpaces = getSortedNameSpaces(proposalNumber, developmentProposal.getS2sOppForms()); 364 365 List<S2SPrintable> formPrintables = new ArrayList<>(); 366 boolean formEntryFlag = true; 367 getNarrativeService().deleteSystemGeneratedNarratives(pdDoc.getDevelopmentProposal().getNarratives()); 368 Forms forms = Forms.Factory.newInstance(); 369 for (String namespace : sortedNameSpaces) { 370 FormMappingInfo info = formMappingService.getFormInfo(namespace,proposalNumber); 371 if(info==null) continue; 372 S2SFormGenerator s2sFormGenerator = s2SFormGeneratorService.getS2SGenerator(proposalNumber,info.getNameSpace()); 373 errors.addAll(s2sFormGenerator.getAuditErrors()); 374 XmlObject formObject = s2sFormGenerator.getFormObject(pdDoc); 375 376 if (s2SValidatorService.validate(formObject, errors, info.getFormName()) && errors.isEmpty()) { 377 String applicationXml = formObject.xmlText(s2SFormGeneratorService.getXmlOptionsPrefixes()); 378 String filteredApplicationXml = s2SDateTimeService.removeTimezoneFactor(applicationXml); 379 byte[] formXmlBytes = filteredApplicationXml.getBytes(); 380 GenericPrintable formPrintable = new GenericPrintable(); 381 // Linkedhashmap is used to preserve the order of entry. 382 Map<String, byte[]> formXmlDataMap = new LinkedHashMap<String, byte[]>(); 383 formXmlDataMap.put(info.getFormName(), formXmlBytes); 384 formPrintable.setStreamMap(formXmlDataMap); 385 386 ArrayList<Source> templates = new ArrayList<Source>(); 387 388 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader()); 389 Resource resource = resourceLoader.getResource(info.getStyleSheet()); 390 391 Source xsltSource = null; 392 try { 393 xsltSource = new StreamSource(resource.getInputStream()); 394 } catch (IOException e) { 395 throw new S2SException(e); 396 } 397 templates.add(xsltSource); 398 formPrintable.setXSLTemplates(templates); 399 400 List<AttachmentData> attachmentList = s2sFormGenerator.getAttachments(); 401 try { 402 if(developmentProposal.getGrantsGovSelectFlag()){ 403 List<S2sAppAttachmentsContract> attachmentLists = new ArrayList<S2sAppAttachmentsContract>(); 404 setFormObject(forms, formObject); 405 saveGrantsGovXml(pdDoc,formEntryFlag,forms,attachmentList,attachmentLists); 406 formEntryFlag = false; 407 } 408 } 409 catch (Exception e) { 410 LOG.error(e.getMessage(), e); 411 } 412 Map<String, byte[]> formAttachments = new LinkedHashMap<String, byte[]>(); 413 if (attachmentList != null && !attachmentList.isEmpty()) { 414 for (AttachmentData attachmentData : attachmentList) { 415 if (!isPdfType(attachmentData.getContent())) 416 continue; 417 StringBuilder attachment = new StringBuilder(); 418 attachment.append(" ATT : "); 419 attachment.append(attachmentData.getContentId()); 420 formAttachments.put(attachment.toString(), 421 attachmentData.getContent()); 422 } 423 } 424 if (formAttachments.size() > 0) { 425 formPrintable.setAttachments(formAttachments); 426 } 427 formPrintables.add(formPrintable); 428 } 429 } 430 final PrintableResult result = new PrintableResult(); 431 result.errors = errors; 432 result.printables = formPrintables; 433 return result; 434 } 435 436 /** 437 * 438 * This method gets formObject from submitted Application 439 * 440 * @param submittedXml 441 * GrantApplicationDocument object of the submitted form. 442 * @param info 443 * form mapping information of the form. 444 * @return XmlObject form object corresponding to the 445 * GrantApplicationDocument and FormMappingInfo objects. 446 * @throws S2SException 447 */ 448 449 protected XmlObject getFormObject(GrantApplicationDocument submittedXml, 450 FormMappingInfo info) { 451 Forms forms = submittedXml.getGrantApplication().getForms(); 452 return forms.newCursor().getObject(); 453 } 454 455 /** 456 * 457 * This method gets attachment contents from narrative based on content ID 458 * 459 * @param pdDoc 460 * Proposal Development Document. 461 * @param contentId 462 * for the particular attachment in the Narrative. 463 * @return byte[] byte array of attachments based on the contentId object. 464 */ 465 466 protected byte[] getAttContent(ProposalDevelopmentDocumentContract pdDoc, 467 String contentId) { 468 String[] contentIds = contentId.split("-"); 469 String[] contentDesc = contentIds[1].split("_"); 470 if (StringUtils.equals(contentIds[0], "N")) { 471 for (NarrativeContract narrative : pdDoc.getDevelopmentProposal() 472 .getNarratives()) { 473 if (narrative.getModuleNumber().equals(Integer.valueOf(contentDesc[0]))) { 474 return narrative.getNarrativeAttachment().getData(); 475 } 476 } 477 } else if (StringUtils.equals(contentIds[0], "B")){ 478 for (ProposalPersonBiographyContract biography : pdDoc.getDevelopmentProposal().getPropPersonBios()) { 479 if (biography.getProposalPersonNumber().equals(Integer.valueOf(contentDesc[0])) 480 && biography.getBiographyNumber().equals(Integer.valueOf(contentDesc[1]))) { 481 return biography.getPersonnelAttachment().getData(); 482 } 483 } 484 } 485 return null; 486 } 487 488 protected KcFile getAttributeContent(ProposalDevelopmentDocumentContract pdDoc, 489 String contentId) { 490 String[] contentIds = contentId.split("-"); 491 String[] contentDesc = contentIds[1].split("_"); 492 if (StringUtils.equals(contentIds[0], "N")) { 493 for (NarrativeContract narrative : pdDoc.getDevelopmentProposal() 494 .getNarratives()) { 495 if (narrative.getModuleNumber().equals(Integer.valueOf(contentDesc[0]))) { 496 return narrative.getNarrativeAttachment(); 497 } 498 } 499 } else if (StringUtils.equals(contentIds[0], "B")){ 500 for (ProposalPersonBiographyContract biography : pdDoc.getDevelopmentProposal().getPropPersonBios()) { 501 if (biography.getProposalPersonNumber().equals(Integer.valueOf(contentDesc[0])) 502 && biography.getBiographyNumber().equals(Integer.valueOf(contentDesc[1]))) { 503 return biography.getPersonnelAttachment(); 504 } 505 } 506 } 507 return null; 508 } 509 /** 510 * 511 * This method gets the latest S2SAppSubmission record from the list of 512 * S2SAppSubmissions. It iterates through the list and returns the record 513 * that has highest SubmissionNo 514 * 515 * @param pdDoc 516 * {@link ProposalDevelopmentDocumentContract} 517 * @return {@link S2sAppSubmissionContract} 518 */ 519 protected S2sAppSubmissionContract getLatestS2SAppSubmission( 520 ProposalDevelopmentDocumentContract pdDoc) { 521 S2sAppSubmissionContract s2sSubmission = null; 522 int submissionNo = 0; 523 for (S2sAppSubmissionContract s2sAppSubmission : pdDoc.getDevelopmentProposal() 524 .getS2sAppSubmission()) { 525 if (s2sAppSubmission.getSubmissionNumber() != null 526 && s2sAppSubmission.getSubmissionNumber().intValue() > submissionNo) { 527 s2sSubmission = s2sAppSubmission; 528 submissionNo = s2sAppSubmission.getSubmissionNumber().intValue(); 529 } 530 } 531 return s2sSubmission; 532 } 533 534 535 536 /** 537 * 538 * This method sorts all the forms in order as specified in 539 * S2sFormBinding.xml and returns the list of namespaces in sorted order. 540 * 541 * @param s2sOppForms 542 * list of S2sOppForms. 543 * @return List<String> list of sorted name spaces. 544 */ 545 protected List<String> getSortedNameSpaces(String proposalNumber,List<? extends S2sOppFormsContract> s2sOppForms) { 546 List<String> orderedNamespaces = new ArrayList<String>(); 547 Set<String> namespaces; 548 formMappingService.getBindings(); 549 Map<Integer, Set<String>> sortedNamespaces = formMappingService.getSortedNameSpaces(); 550 List<Integer> sortedIndices = new ArrayList<Integer>(sortedNamespaces 551 .keySet()); 552 int index = 0; 553 for (Integer sortedIndex : sortedIndices) { 554 for (S2sOppFormsContract oppForm : s2sOppForms) { 555 namespaces = sortedNamespaces.get(sortedIndex); 556 for (String namespace : namespaces) { 557 if (namespace.equals(oppForm.getOppNameSpace())) { 558 if (Boolean.TRUE.equals(oppForm.getSelectToPrint())) { 559 orderedNamespaces.add(index++, namespace); 560 } 561 } 562 } 563 } 564 } 565 List<String> userAttachedFormNamespaces = findUserAttachedNamespaces(proposalNumber); 566 for (S2sOppFormsContract oppForm : s2sOppForms) { 567 if(userAttachedFormNamespaces.contains(oppForm.getOppNameSpace())){ 568 orderedNamespaces.add(oppForm.getOppNameSpace()); 569 } 570 } 571 return orderedNamespaces; 572 } 573 574 private List<String> findUserAttachedNamespaces(String proposalNumber) { 575 return userAttachedFormService.findFormNamespaces(proposalNumber); 576 } 577 578 /** 579 * 580 * Setter for {@link org.kuali.coeus.s2sgen.impl.generate.S2SFormGeneratorRetrievalService} 581 * 582 * @param s2SFormGeneratorService 583 */ 584 public void setS2SFormGeneratorService( 585 S2SFormGeneratorRetrievalService s2SFormGeneratorService) { 586 this.s2SFormGeneratorService = s2SFormGeneratorService; 587 } 588 589 /** 590 * 591 * Setter for {@link org.kuali.coeus.s2sgen.impl.generate.S2SFormGeneratorRetrievalService} 592 * 593 * @param s2SValidatorService 594 */ 595 public void setS2SValidatorService(S2SValidatorService s2SValidatorService) { 596 this.s2SValidatorService = s2SValidatorService; 597 } 598 599 protected boolean isPdfType(byte[] data) { 600 final int ATTRIBUTE_CHUNK_SIZE = 1200;// increased for ppt 601 final String PRE_HEXA = "0x"; 602 603 boolean retValue = false; 604 String str[] = { "25", "50", "44", "46" }; 605 byte byteCheckArr[] = new byte[4]; 606 byte byteDataArr[] = new byte[4]; 607 608 for (int byteIndex = 0; byteIndex < byteCheckArr.length; byteIndex++) { 609 byteCheckArr[byteIndex] = Integer.decode(PRE_HEXA + str[byteIndex]) 610 .byteValue(); 611 } 612 613 int startPoint, endPoint; 614 615 startPoint = 0; 616 endPoint = (ATTRIBUTE_CHUNK_SIZE > (data.length / 2)) ? data.length / 2 617 : ATTRIBUTE_CHUNK_SIZE; 618 619 for (int forwardIndex = startPoint; forwardIndex < endPoint 620 - str.length; forwardIndex++) { 621 if (forwardIndex == 0) { 622 // Fill All Data 623 for (int fillIndex = 0; fillIndex < str.length; fillIndex++) { 624 byteDataArr[fillIndex] = toUnsignedByte(data[fillIndex]); 625 } 626 } else { 627 // Push Data, Fill last index 628 for (int fillIndex = 0; fillIndex < str.length - 1; fillIndex++) { 629 byteDataArr[fillIndex] = byteDataArr[fillIndex + 1]; 630 } 631 byteDataArr[str.length - 1] = toUnsignedByte(data[str.length 632 - 1 + forwardIndex]); 633 } 634 635 if (new String(byteCheckArr).equals(new String(byteDataArr))) { 636 retValue = true; 637 } 638 } 639 640 return retValue; 641 } 642 643 /** 644 * convert int to unsigned byte 645 */ 646 protected static byte toUnsignedByte(int intVal) { 647 byte byteVal; 648 if (intVal > 127) { 649 int temp = intVal - 256; 650 byteVal = (byte) temp; 651 } else { 652 byteVal = (byte) intVal; 653 } 654 return byteVal; 655 } 656 657 public NarrativeService getNarrativeService() { 658 return narrativeService; 659 } 660 661 public void setNarrativeService(NarrativeService narrativeService) { 662 this.narrativeService = narrativeService; 663 } 664 665 public S2SPrintingService getS2SPrintingService() { 666 return s2SPrintingService; 667 } 668 669 public void setS2SPrintingService(S2SPrintingService s2SPrintingService) { 670 this.s2SPrintingService = s2SPrintingService; 671 } 672 protected void setFormObject(Forms forms, XmlObject formObject) { 673 // Create a cursor from the grants.gov form 674 XmlCursor formCursor = formObject.newCursor(); 675 formCursor.toStartDoc(); 676 formCursor.toNextToken(); 677 678 // Create a cursor from the Forms object 679 XmlCursor metaGrantCursor = forms.newCursor(); 680 metaGrantCursor.toNextToken(); 681 682 // Add the form to the Forms object. 683 formCursor.moveXml(metaGrantCursor); 684 } 685 686 public S2SConfigurationService getS2SConfigurationService() { 687 return s2SConfigurationService; 688 } 689 690 public void setS2SConfigurationService(S2SConfigurationService s2SConfigurationService) { 691 this.s2SConfigurationService = s2SConfigurationService; 692 } 693 694 public S2sApplicationService getS2sApplicationService() { 695 return s2sApplicationService; 696 } 697 698 public void setS2sApplicationService(S2sApplicationService s2sApplicationService) { 699 this.s2sApplicationService = s2sApplicationService; 700 } 701 702 public S2SFormGeneratorRetrievalService getS2SFormGeneratorService() { 703 return s2SFormGeneratorService; 704 } 705 706 public S2SValidatorService getS2SValidatorService() { 707 return s2SValidatorService; 708 } 709 710 public FormMappingService getFormMappingService() { 711 return formMappingService; 712 } 713 714 public void setFormMappingService(FormMappingService formMappingService) { 715 this.formMappingService = formMappingService; 716 } 717 718 public UserAttachedFormService getUserAttachedFormService() { 719 return userAttachedFormService; 720 } 721 722 public void setUserAttachedFormService(UserAttachedFormService userAttachedFormService) { 723 this.userAttachedFormService = userAttachedFormService; 724 } 725 726 public S2SDateTimeService getS2SDateTimeService() { 727 return s2SDateTimeService; 728 } 729 730 public void setS2SDateTimeService(S2SDateTimeService s2SDateTimeService) { 731 this.s2SDateTimeService = s2SDateTimeService; 732 } 733 734 protected static class PrintableResult { 735 private List<S2SPrintable> printables; 736 private List<AuditError> errors; 737 } 738}