View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.batch.web;
18  
19  import org.apache.log4j.Logger;
20  import org.apache.struts.action.ActionForm;
21  import org.apache.struts.action.ActionForward;
22  import org.apache.struts.action.ActionMapping;
23  import org.apache.struts.upload.FormFile;
24  import org.kuali.rice.kew.batch.*;
25  import org.kuali.rice.kew.service.KEWServiceLocator;
26  import org.kuali.rice.kew.util.Utilities;
27  import org.kuali.rice.kew.web.session.UserSession;
28  import org.kuali.rice.kim.bo.types.dto.AttributeSet;
29  import org.kuali.rice.kim.service.KIMServiceLocator;
30  import org.kuali.rice.kim.util.KimCommonUtils;
31  import org.kuali.rice.kim.util.KimConstants;
32  import org.kuali.rice.kns.exception.AuthorizationException;
33  import org.kuali.rice.kns.util.KNSConstants;
34  import org.kuali.rice.kns.web.struts.action.KualiAction;
35  
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  import java.io.File;
39  import java.io.FileOutputStream;
40  import java.io.IOException;
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.List;
44  
45  
46  /**
47   * Struts action that accepts uploaded files and feeds them to the XmlIngesterService
48   * @see org.kuali.rice.kew.batch.XmlIngesterService
49   * @see org.kuali.rice.kew.batch.web.IngesterForm
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  public class IngesterAction extends KualiAction {
53      private static final Logger LOG = Logger.getLogger(IngesterAction.class);
54  
55      public ActionForward execute(
56              ActionMapping mapping,
57              ActionForm form,
58              HttpServletRequest request,
59              HttpServletResponse response)
60              throws Exception {
61  
62      	checkAuthorization(form, "");
63  
64          LOG.debug(request.getMethod());
65          if (!"post".equals(request.getMethod().toLowerCase())) {
66              LOG.debug("returning to view");
67              return mapping.findForward("view");
68          }
69  
70          IngesterForm iform = (IngesterForm) form;
71  
72          List<String> messages = new ArrayList<String>();
73          List<File> tempFiles = new ArrayList<File>();
74          try {
75              Collection<FormFile> files = iform.getFiles();
76              List<XmlDocCollection> collections = new ArrayList<XmlDocCollection>(files.size());
77              LOG.debug(files);
78              LOG.debug("" + files.size());
79  
80              for (FormFile file1 : files)
81              {
82                  if (file1.getFileName() == null || file1.getFileName().length() == 0) continue;
83                  if (file1.getFileData() == null)
84                  {
85                      messages.add("File '" + file1.getFileName() + "' contained no data");
86                      continue;
87                  }
88                  LOG.debug("Processing file: " + file1.getFileName());
89                  // ok, we have to copy it to *another* file because Struts doesn't give us a File
90                  // reference (which itself is not a bad abstraction) and XmlDocs based on ZipFile
91                  // can't be constructed without a file reference.
92                  FileOutputStream fos = null;
93                  File temp = null;
94                  try
95                  {
96                      temp = File.createTempFile("ingester", null);
97                      tempFiles.add(temp);
98                      fos = new FileOutputStream(temp);
99                      fos.write(file1.getFileData());
100                 } catch (IOException ioe)
101                 {
102                     messages.add("Error copying file data for '" + file1.getFileName() + "': " + ioe);
103                     continue;
104                 } finally
105                 {
106                     if (fos != null) try
107                     {
108                         fos.close();
109                     } catch (IOException ioe)
110                     {
111                         LOG.error("Error closing temp file output stream: " + temp, ioe);
112                     }
113                 }
114                 if (file1.getFileName().toLowerCase().endsWith(".zip"))
115                 {
116                     try
117                     {
118                         collections.add(new ZipXmlDocCollection(temp));
119                     } catch (IOException ioe)
120                     {
121                         String message = "Unable to load file: " + file1;
122                         LOG.error(message);
123                         messages.add(message);
124                     }
125                 } else if (file1.getFileName().endsWith(".xml"))
126                 {
127                     collections.add(new FileXmlDocCollection(temp, file1.getFileName()));
128                 } else
129                 {
130                     messages.add("Ignoring extraneous file: " + file1.getFileName());
131                 }
132             }
133 
134             if (collections.size() == 0) {
135                 String message = "No valid files to ingest";
136                 LOG.debug(message);
137                 messages.add(message);
138             } else {
139                 // wrap in composite collection to make transactional
140                 CompositeXmlDocCollection compositeCollection = new CompositeXmlDocCollection(collections);
141                 int totalProcessed = 0;
142                 List<XmlDocCollection> c = new ArrayList<XmlDocCollection>(1);
143                 c.add(compositeCollection);
144                 try {
145                     Collection<XmlDocCollection> failed = KEWServiceLocator.getXmlIngesterService().ingest(c, UserSession.getAuthenticatedUser().getPrincipal().getPrincipalId());
146                     boolean txFailed = failed.size() > 0;
147                     if (txFailed) {
148                         messages.add("Ingestion failed");
149                     }
150                     for (XmlDocCollection collection1 : collections)
151                     {
152                         List<? extends XmlDoc> docs = collection1.getXmlDocs();
153                         for (XmlDoc doc1 : docs)
154                         {
155                             if (doc1.isProcessed())
156                             {
157                                 if (!txFailed)
158                                 {
159                                     totalProcessed++;
160                                     messages.add("Ingested xml doc: " + doc1.getName() + (doc1.getProcessingMessage() == null ? "" : "\n" + doc1.getProcessingMessage()));
161                                 } else
162                                 {
163                                     messages.add("Rolled back doc: " + doc1.getName() + (doc1.getProcessingMessage() == null ? "" : "\n" + doc1.getProcessingMessage()));
164                                 }
165                             } else
166                             {
167                                 messages.add("Failed to ingest xml doc: " + doc1.getName() + (doc1.getProcessingMessage() == null ? "" : "\n" + doc1.getProcessingMessage()));
168                             }
169                         }
170                     }
171                 } catch (Exception e) {
172                     String message = "Error during ingest";
173                     LOG.error(message, e);
174                     messages.add(message + ": " + e  + ":\n" + Utilities.collectStackTrace(e));
175                 }
176                 if (totalProcessed == 0) {
177                     String message = "No xml docs ingested";
178                     LOG.debug(message);
179                     messages.add(message);
180                 }
181             }
182         } finally {
183             if (tempFiles.size() > 0) {
184                 for (File tempFile : tempFiles)
185                 {
186                     if (!tempFile.delete())
187                     {
188                         LOG.warn("Error deleting temp file: " + tempFile);
189                     }
190                 }
191             }
192         }
193 
194         request.setAttribute("messages", messages);
195         return mapping.findForward("view");
196     }
197 
198     protected void checkAuthorization( ActionForm form, String methodToCall) throws AuthorizationException
199     {
200     	String principalId = UserSession.getAuthenticatedUser().getPrincipalId();
201     	AttributeSet roleQualifier = new AttributeSet();
202     	AttributeSet permissionDetails = KimCommonUtils.getNamespaceAndActionClass(this.getClass());
203 
204         if (!KIMServiceLocator.getIdentityManagementService().isAuthorizedByTemplateName(principalId, KNSConstants.KNS_NAMESPACE,
205         		KimConstants.PermissionTemplateNames.USE_SCREEN, permissionDetails, roleQualifier ))
206         {
207             throw new AuthorizationException(UserSession.getAuthenticatedUser().getPrincipalName(),
208             		methodToCall,
209             		this.getClass().getSimpleName());
210         }
211     }
212 
213 
214 }