001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.administration; 029 030import org.opencms.file.CmsResource; 031import org.opencms.jsp.CmsJspActionElement; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsIllegalArgumentException; 034import org.opencms.main.OpenCms; 035import org.opencms.util.CmsRfsException; 036import org.opencms.util.CmsStringUtil; 037import org.opencms.workplace.CmsDialog; 038import org.opencms.workplace.CmsWorkplaceSettings; 039 040import java.io.File; 041import java.io.FileNotFoundException; 042import java.io.FileOutputStream; 043import java.io.IOException; 044import java.io.OutputStream; 045import java.util.Iterator; 046 047import javax.servlet.ServletException; 048import javax.servlet.http.HttpServletRequest; 049import javax.servlet.http.HttpServletResponse; 050import javax.servlet.jsp.JspException; 051import javax.servlet.jsp.JspWriter; 052import javax.servlet.jsp.PageContext; 053 054import org.apache.commons.fileupload.FileItem; 055 056/** 057 * Abstract class to upload a zip file containing VFS resources with HTTP upload.<p> 058 * 059 * @since 6.0.0 060 */ 061public abstract class A_CmsImportFromHttp extends CmsDialog { 062 063 /** The dialog type. */ 064 public static final String DIALOG_TYPE = "ImportHttp"; 065 066 /** Import file request parameter. */ 067 public static final String PARAM_IMPORTFILE = "importfile"; 068 069 /** The exception thrown if an error occurs. */ 070 private CmsException m_exception; 071 072 /** The import file name that is uploaded. */ 073 private String m_paramImportfile; 074 075 /** 076 * Public constructor with JSP action element.<p> 077 * 078 * @param jsp an initialized JSP action element 079 */ 080 public A_CmsImportFromHttp(CmsJspActionElement jsp) { 081 082 super(jsp); 083 } 084 085 /** 086 * Public constructor with JSP variables.<p> 087 * 088 * @param context the JSP page context 089 * @param req the JSP request 090 * @param res the JSP response 091 */ 092 public A_CmsImportFromHttp(PageContext context, HttpServletRequest req, HttpServletResponse res) { 093 094 this(new CmsJspActionElement(context, req, res)); 095 } 096 097 /** 098 * Performs the import operation after "OK" has been pressed.<p> 099 * 100 * @throws IOException in case of errors forwarding to the required result page 101 * @throws ServletException in case of errors forwarding to the required result page 102 */ 103 public abstract void actionCommit() throws IOException, ServletException; 104 105 /** 106 * Performs the dialog actions depending on the initialized action and displays the dialog form.<p> 107 * 108 * @throws JspException if dialog actions fail 109 * @throws IOException if writing to the JSP out fails, or in case of errors forwarding to the required result page 110 * @throws ServletException in case of errors forwarding to the required result page 111 */ 112 public void displayDialog() throws IOException, JspException, ServletException { 113 114 switch (getAction()) { 115 116 case ACTION_CANCEL: 117 // ACTION: cancel button pressed 118 actionCloseDialog(); 119 break; 120 121 case ACTION_OK: 122 // ACTION: ok button pressed 123 setParamAction(DIALOG_OK); 124 actionCommit(); 125 if (getException() == null) { 126 // file successfully copied to server 127 break; 128 } 129 130 //$FALL-THROUGH$ 131 case ACTION_DEFAULT: 132 default: 133 // ACTION: show dialog (default) 134 setParamAction(DIALOG_OK); 135 JspWriter out = getJsp().getJspContext().getOut(); 136 out.print(defaultActionHtml()); 137 } 138 } 139 140 /** 141 * Gets the return uri for this dialog.<p> 142 * 143 * @return return uri for this dialog 144 */ 145 public abstract String getDialogReturnUri(); 146 147 /** 148 * Gets the localized import message text for the input form.<p> 149 * 150 * @return localized import message text for the input form 151 */ 152 public abstract String getImportMessage(); 153 154 /** 155 * Returns the import file name that is uploaded.<p> 156 * 157 * @return the import file name that is uploaded 158 */ 159 public String getParamImportfile() { 160 161 return m_paramImportfile; 162 } 163 164 /** 165 * Gets the localized start text for the input form.<p> 166 * 167 * @return localized start text for the input form 168 */ 169 public abstract String getStarttext(); 170 171 /** 172 * Sets the import file name that is uploaded.<p> 173 * 174 * @param importfile the import file name that is uploaded 175 */ 176 public void setParamImportfile(String importfile) { 177 178 m_paramImportfile = importfile; 179 } 180 181 /** 182 * Html code for the additional parameters.<p> 183 * 184 * @return html code 185 */ 186 protected String getAdditionalParameters() { 187 188 // do nothing 189 return ""; 190 } 191 192 /** 193 * Gets a database import file from the client and copies it to the server.<p> 194 * 195 * @param destination the destination of the file on the server 196 * 197 * @return the name of the file or null if something went wrong when importing the file 198 * 199 * @throws CmsIllegalArgumentException if the specified file name is invalid 200 * @throws CmsRfsException if generating folders or files on the server fails 201 */ 202 protected String copyFileToServer(String destination) throws CmsIllegalArgumentException, CmsRfsException { 203 204 // get the file item from the multipart request 205 Iterator<FileItem> i = getMultiPartFileItems().iterator(); 206 FileItem fi = null; 207 while (i.hasNext()) { 208 fi = i.next(); 209 if (fi.getName() != null) { 210 // found the file object, leave iteration 211 break; 212 } else { 213 // this is no file object, check next item 214 continue; 215 } 216 } 217 218 String fileName = null; 219 220 if ((fi != null) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(fi.getName())) { 221 // file name has been specified, upload the file 222 fileName = fi.getName(); 223 byte[] content = fi.get(); 224 fi.delete(); 225 // get the file name without folder information 226 fileName = CmsResource.getName(fileName.replace('\\', '/')); 227 // first create the folder if it does not exist 228 File discFolder = new File( 229 OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 230 OpenCms.getSystemInfo().getPackagesRfsPath() + File.separator)); 231 if (!discFolder.exists()) { 232 if (!discFolder.mkdir()) { 233 throw new CmsRfsException(Messages.get().container(Messages.ERR_FOLDER_NOT_CREATED_0)); 234 } 235 } 236 // write the file into the packages folder of the OpenCms server 237 File discFile = new File( 238 OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(destination + File.separator + fileName)); 239 try { 240 // write the new file to disk 241 OutputStream s = new FileOutputStream(discFile); 242 s.write(content); 243 s.close(); 244 } catch (FileNotFoundException e) { 245 throw new CmsRfsException(Messages.get().container(Messages.ERR_FILE_NOT_FOUND_1, fileName, e)); 246 } catch (IOException e) { 247 throw new CmsRfsException(Messages.get().container(Messages.ERR_FILE_NOT_WRITTEN_0, e)); 248 } 249 } else { 250 // no file name has been specified, throw exception 251 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_FILE_NOT_SPECIFIED_0)); 252 } 253 // set the request parameter to the name of the import file 254 setParamImportfile(fileName); 255 return fileName; 256 } 257 258 /** 259 * Creates the HTML for the error message if validation errors were found.<p> 260 * 261 * @return the HTML for the error message if validation errors were found 262 */ 263 protected String createDialogErrorMessage() { 264 265 if (getException() != null) { 266 StringBuffer result = new StringBuffer(8); 267 result.append(dialogBlockStart("")); 268 result.append("<table border=\"0\">\n"); 269 result.append("<tr><td><img src=\""); 270 result.append(getSkinUri()).append("commons/"); 271 result.append("error.png"); 272 result.append("\" border=\"0\" alt=\"\"></td><td class=\"xmlTdError maxwidth\">"); 273 Throwable t = getException(); 274 while (t != null) { 275 result.append(t.getLocalizedMessage()); 276 t = t.getCause(); 277 if (t != null) { 278 result.append("<br>"); 279 } 280 } 281 result.append("</table>\n"); 282 result.append(dialogBlockEnd()); 283 return result.toString(); 284 } 285 return ""; 286 } 287 288 /** 289 * Returns the HTML to build the input form of the upload dialog.<p> 290 * 291 * @return the HTML to build the input form of the upload dialog 292 */ 293 protected String defaultActionHtml() { 294 295 StringBuffer result = new StringBuffer(32); 296 297 result.append(htmlStart()); 298 result.append(bodyStart(null)); 299 result.append(dialogStart()); 300 result.append(dialogContentStart("")); 301 result.append("<form name=\"main\" class=\"nomargin\" action=\""); 302 result.append(getJsp().link(getDialogReturnUri())); 303 result.append("\" method=\"post\" onsubmit=\"submitAction('"); 304 result.append(DIALOG_OK); 305 result.append("', null, 'main');\" enctype=\"multipart/form-data\">\n"); 306 result.append(paramsAsHidden()); 307 if (getParamFramename() == null) { 308 result.append("<input type=\"hidden\" name=\""); 309 result.append(PARAM_FRAMENAME); 310 result.append("\" value=\"\">"); 311 } 312 result.append(createDialogErrorMessage()); 313 result.append(dialogBlockStart(getStarttext())); 314 result.append("<table border=\"0\" width=\"100%\">\n"); 315 result.append("<tr>\n\t<td style=\"white-space: nowrap;\" unselectable=\"on\">"); 316 result.append(getImportMessage()); 317 result.append(":</td>\n"); 318 result.append("\t<td class=\"maxwidth\">"); 319 result.append("<input type=\"file\" name=\""); 320 result.append(PARAM_IMPORTFILE); 321 result.append("\" class=\"maxwidth\" accept=\"application/zip\">"); 322 result.append("</td>\n</tr>"); 323 result.append(getAdditionalParameters()); 324 result.append("</table>\n"); 325 result.append(dialogBlockEnd()); 326 327 result.append(dialogContentEnd()); 328 result.append(dialogButtonsOkCancel()); 329 result.append("</form>\n"); 330 result.append(dialogEnd()); 331 result.append(bodyEnd()); 332 result.append(htmlEnd()); 333 return result.toString(); 334 } 335 336 /** 337 * Returns the dialog exception.<p> 338 * 339 * @return the dialog exception 340 */ 341 protected CmsException getException() { 342 343 return m_exception; 344 } 345 346 /** 347 * @see org.opencms.workplace.CmsWorkplace#initMessages() 348 */ 349 @Override 350 protected abstract void initMessages(); 351 352 /** 353 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 354 */ 355 @Override 356 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 357 358 // set the dialog type 359 setParamDialogtype(getClass().getName()); 360 361 // fill the parameter values in the get/set methods 362 fillParamValues(request); 363 364 // set the action for the JSP switch 365 if (DIALOG_OK.equals(getParamAction())) { 366 // ok button pressed 367 setAction(ACTION_OK); 368 } else if (DIALOG_CANCEL.equals(getParamAction())) { 369 // cancel button pressed 370 setAction(ACTION_CANCEL); 371 } else { 372 // first dialog call, set the default action 373 setAction(ACTION_DEFAULT); 374 } 375 } 376 377 /** 378 * Sets the dialog exception.<p> 379 * 380 * @param exception the dialog exception 381 */ 382 protected void setException(CmsException exception) { 383 384 m_exception = exception; 385 } 386}