001 package org.apache.myfaces.tobago.fileupload;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one or more
005 * contributor license agreements. See the NOTICE file distributed with
006 * this work for additional information regarding copyright ownership.
007 * The ASF licenses this file to You under the Apache License, Version 2.0
008 * (the "License"); you may not use this file except in compliance with
009 * the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020 import org.slf4j.Logger;
021 import org.slf4j.LoggerFactory;
022 import org.apache.myfaces.tobago.internal.util.JndiUtils;
023 import org.apache.myfaces.tobago.internal.webapp.TobagoMultipartFormdataRequest;
024
025 import javax.faces.FacesException;
026 import javax.faces.application.FacesMessage;
027 import javax.faces.context.FacesContext;
028 import javax.faces.context.FacesContextFactory;
029 import javax.faces.lifecycle.Lifecycle;
030 import javax.naming.InitialContext;
031 import javax.naming.NamingException;
032 import javax.servlet.http.HttpServletRequest;
033 import java.io.File;
034
035 /**
036 * This FacesContextFactory handles multipart request. Add the tobago-fileupload.jar to your web application.
037 * Configuration:
038 *
039 * <p><blockquote><pre>
040 <env-entry>
041 <description>Set the size limit for uploaded files. Default value is 1 MB.
042 Format: 10 = 10 bytes
043 10k = 10 KB
044 10m = 10 MB
045 1g = 1 GB
046 </description>
047 <env-entry-name>uploadMaxFileSize</env-entry-name>
048 <env-entry-type>java.lang.String</env-entry-type>
049 <env-entry-value>20m</env-entry-value>
050 </env-entry>
051 <env-entry>
052 <description>Set the upload repository path for uploaded files.
053 Default value is java.io.tmpdir.</description>
054 <env-entry-name>uploadRepositoryPath</env-entry-name>
055 <env-entry-type>java.lang.String</env-entry-type>
056 <env-entry-value>/tmp</env-entry-value>
057 </env-entry>
058 </pre></blockquote><p>
059
060 *
061 */
062 public class FileUploadFacesContextFactoryImpl extends FacesContextFactory {
063 private static final Logger LOG = LoggerFactory.getLogger(FileUploadFacesContextFactoryImpl.class);
064 private FacesContextFactory facesContextFactory;
065 private String repositoryPath = System.getProperty("java.io.tmpdir");
066 private long maxSize = TobagoMultipartFormdataRequest.ONE_MB;
067
068 public FileUploadFacesContextFactoryImpl(FacesContextFactory facesContextFactory) {
069 // TODO get Configuration from env entries in the web.xml or context-param
070 this.facesContextFactory = facesContextFactory;
071 if (LOG.isDebugEnabled()) {
072 LOG.debug("Wrap FacesContext for file upload");
073 }
074 InitialContext ic = null;
075 try {
076 ic = new InitialContext();
077
078 try {
079 String repositoryPath = (String) JndiUtils.getJndiProperty(ic, "uploadRepositoryPath");
080 if (repositoryPath != null) {
081 File file = new File(repositoryPath);
082 if (!file.exists()) {
083 LOG.error("Given repository Path for "
084 + getClass().getName() + " " + repositoryPath + " doesn't exists");
085 } else if (!file.isDirectory()) {
086 LOG.error("Given repository Path for "
087 + getClass().getName() + " " + repositoryPath + " is not a directory");
088 } else {
089 this.repositoryPath = repositoryPath;
090 }
091 }
092 } catch (NamingException ne) {
093 // ignore
094 }
095
096 try {
097 String size = (String) JndiUtils.getJndiProperty(ic, "uploadMaxFileSize");
098 maxSize = TobagoMultipartFormdataRequest.getMaxSize(size);
099 } catch (NamingException ne) {
100 // ignore
101 }
102 } catch (NamingException e) {
103 // ignore no naming available
104 } finally {
105 if (ic != null) {
106 try {
107 ic.close();
108 } catch (NamingException e) {
109 // ignore
110 }
111 }
112 }
113 if (LOG.isInfoEnabled()) {
114 LOG.info("Configure uploadMaxFileSize for "+ getClass().getName() + " to "+ this.maxSize);
115 LOG.info("Configure uploadRepositryPath for "+ getClass().getName() + " to "+ this.repositoryPath);
116 }
117 }
118
119 public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
120 throws FacesException {
121 if (request instanceof HttpServletRequest && !(request instanceof TobagoMultipartFormdataRequest)) {
122 String contentType = ((HttpServletRequest) request).getContentType();
123 if (contentType != null && contentType.toLowerCase().startsWith("multipart/form-data")) {
124 if (LOG.isDebugEnabled()) {
125 LOG.debug("Wrap HttpServletRequest for file upload");
126 }
127 try {
128 request = new TobagoMultipartFormdataRequest((HttpServletRequest) request, repositoryPath, maxSize);
129 } catch (FacesException e) {
130 LOG.error("", e);
131 FacesContext facesContext = facesContextFactory.getFacesContext(context, request, response, lifecycle);
132 // TODO better Message i18n Message?
133 FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getCause().getMessage(), null);
134 facesContext.addMessage(null, facesMessage);
135 facesContext.renderResponse();
136 return facesContext;
137 }
138 }
139 }
140 return facesContextFactory.getFacesContext(context, request, response, lifecycle);
141 }
142 }