001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.tools.modules; 029 030import org.opencms.configuration.CmsConfigurationException; 031import org.opencms.jsp.CmsJspActionElement; 032import org.opencms.main.CmsRuntimeException; 033import org.opencms.main.OpenCms; 034import org.opencms.module.CmsModule; 035import org.opencms.module.CmsModuleDependency; 036import org.opencms.module.CmsModuleImportExportHandler; 037import org.opencms.module.CmsModuleManager; 038import org.opencms.widgets.CmsDisplayWidget; 039import org.opencms.widgets.CmsSelectWidget; 040import org.opencms.widgets.CmsSelectWidgetOption; 041import org.opencms.workplace.CmsWidgetDialog; 042import org.opencms.workplace.CmsWidgetDialogParameter; 043import org.opencms.workplace.CmsWorkplaceSettings; 044import org.opencms.workplace.tools.CmsToolDialog; 045import org.opencms.workplace.tools.CmsToolManager; 046 047import java.io.File; 048import java.io.IOException; 049import java.text.Collator; 050import java.util.ArrayList; 051import java.util.Collections; 052import java.util.Comparator; 053import java.util.HashMap; 054import java.util.List; 055import java.util.Map; 056 057import jakarta.servlet.ServletException; 058import jakarta.servlet.http.HttpServletRequest; 059import jakarta.servlet.http.HttpServletResponse; 060import jakarta.servlet.jsp.PageContext; 061 062/** 063 * Class to upload a module from the server.<p> 064 * 065 * @since 6.0.0 066 */ 067public class CmsModulesUploadFromServer extends CmsWidgetDialog { 068 069 /** 070 * A <code>{@link Comparator}</code> for <code>{@link CmsSelectWidgetOption}</code> instances.<p> 071 * 072 * @since 7.0.3 073 * 074 */ 075 protected class ComparatorSelectWidgetOption implements Comparator { 076 077 /** Collator used / wrapped. */ 078 private Collator m_collator = Collator.getInstance(getLocale()); 079 080 /** 081 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) 082 */ 083 public int compare(Object arg0, Object arg1) { 084 085 CmsSelectWidgetOption o1 = (CmsSelectWidgetOption)arg0; 086 CmsSelectWidgetOption o2 = (CmsSelectWidgetOption)arg1; 087 return m_collator.compare(o1.getOption(), o2.getOption()); 088 } 089 090 } 091 092 /** The dialog type. */ 093 public static final String DIALOG_TYPE = "ModulesUploadServer"; 094 095 /** The import action. */ 096 protected static final String IMPORT_ACTION_REPORT = "/system/workplace/admin/modules/reports/import.jsp"; 097 098 /** Defines which pages are valid for this dialog. */ 099 public static final String[] PAGES = {"page1"}; 100 101 /** Modulename parameter. */ 102 public static final String PARAM_MODULENAME = "modulename"; 103 104 /** The replace action. */ 105 protected static final String REPLACE_ACTION_REPORT = "/system/workplace/admin/modules/reports/replace.jsp"; 106 107 /** Modulename. */ 108 private String m_moduleupload; 109 110 /** 111 * Public constructor with JSP action element.<p> 112 * 113 * @param jsp an initialized JSP action element 114 */ 115 public CmsModulesUploadFromServer(CmsJspActionElement jsp) { 116 117 super(jsp); 118 } 119 120 /** 121 * Public constructor with JSP variables.<p> 122 * 123 * @param context the JSP page context 124 * @param req the JSP request 125 * @param res the JSP response 126 */ 127 public CmsModulesUploadFromServer(PageContext context, HttpServletRequest req, HttpServletResponse res) { 128 129 this(new CmsJspActionElement(context, req, res)); 130 } 131 132 /** 133 * @see org.opencms.workplace.CmsWidgetDialog#actionCommit() 134 */ 135 @Override 136 public void actionCommit() throws IOException, ServletException { 137 138 List errors = new ArrayList(); 139 CmsModule module = null; 140 try { 141 String importpath = OpenCms.getSystemInfo().getPackagesRfsPath(); 142 importpath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf( 143 importpath + "modules/" + m_moduleupload); 144 module = CmsModuleImportExportHandler.readModuleFromImport(importpath); 145 146 // check if all dependencies are fulfilled 147 List dependencies = OpenCms.getModuleManager().checkDependencies( 148 module, 149 CmsModuleManager.DEPENDENCY_MODE_IMPORT); 150 if (!dependencies.isEmpty()) { 151 StringBuffer dep = new StringBuffer(32); 152 for (int i = 0; i < dependencies.size(); i++) { 153 CmsModuleDependency dependency = (CmsModuleDependency)dependencies.get(i); 154 dep.append("\n - "); 155 dep.append(dependency.getName()); 156 dep.append(" (Version: "); 157 dep.append(dependency.getVersion()); 158 dep.append(")"); 159 } 160 errors.add( 161 new CmsRuntimeException( 162 Messages.get().container( 163 Messages.ERR_ACTION_MODULE_DEPENDENCY_2, 164 m_moduleupload, 165 new String(dep)))); 166 } 167 168 } catch (CmsConfigurationException e) { 169 errors.add( 170 new CmsRuntimeException( 171 Messages.get().container(Messages.ERR_ACTION_MODULE_UPLOAD_1, m_moduleupload), 172 e)); 173 } 174 175 if ((module != null) && errors.isEmpty()) { 176 177 // refresh the list 178 Map objects = (Map)getSettings().getListObject(); 179 if (objects != null) { 180 objects.remove(CmsModulesList.class.getName()); 181 } 182 183 // redirect 184 Map param = new HashMap(); 185 param.put(CmsModulesList.PARAM_MODULE, m_moduleupload); 186 param.put(PARAM_STYLE, CmsToolDialog.STYLE_NEW); 187 param.put(PARAM_CLOSELINK, CmsToolManager.linkForToolPath(getJsp(), "/modules")); 188 if (OpenCms.getModuleManager().hasModule(module.getName())) { 189 param.put(PARAM_MODULENAME, module.getName()); 190 getToolManager().jspForwardPage(this, REPLACE_ACTION_REPORT, param); 191 } else { 192 getToolManager().jspForwardPage(this, IMPORT_ACTION_REPORT, param); 193 } 194 } 195 196 // set the list of errors to display when saving failed 197 setCommitErrors(errors); 198 } 199 200 /** 201 * Gets the module parameter.<p> 202 * 203 * @return the module parameter 204 */ 205 public String getModuleupload() { 206 207 return m_moduleupload; 208 } 209 210 /** 211 * Sets the module parameter.<p> 212 * @param module the module parameter 213 */ 214 public void setModuleupload(String module) { 215 216 m_moduleupload = module; 217 } 218 219 /** 220 * Creates the dialog HTML for all defined widgets of the named dialog (page).<p> 221 * 222 * @param dialog the dialog (page) to get the HTML for 223 * @return the dialog HTML for all defined widgets of the named dialog (page) 224 */ 225 @Override 226 protected String createDialogHtml(String dialog) { 227 228 StringBuffer result = new StringBuffer(1024); 229 230 // create table 231 result.append(createWidgetTableStart()); 232 233 // show error header once if there were validation errors 234 result.append(createWidgetErrorHeader()); 235 236 if (dialog.equals(PAGES[0])) { 237 result.append(dialogBlockStart(key("label.uploadfromserver"))); 238 result.append(createWidgetTableStart()); 239 result.append(createDialogRowsHtml(0, 0)); 240 result.append(createWidgetTableEnd()); 241 result.append(dialogBlockEnd()); 242 } 243 244 // close table 245 result.append(createWidgetTableEnd()); 246 247 return result.toString(); 248 } 249 250 /** 251 * Creates the list of widgets for this dialog.<p> 252 */ 253 @Override 254 protected void defineWidgets() { 255 256 List selectOptions = getModulesFromServer(); 257 258 if (selectOptions.isEmpty()) { 259 // no import modules available, display message 260 addWidget( 261 new CmsWidgetDialogParameter( 262 this, 263 "moduleupload", 264 PAGES[0], 265 new CmsDisplayWidget(key(Messages.GUI_MODULES_IMPORT_NOT_AVAILABLE_0)))); 266 } else { 267 // add the file select box widget 268 addWidget(new CmsWidgetDialogParameter(this, "moduleupload", PAGES[0], new CmsSelectWidget(selectOptions))); 269 } 270 } 271 272 /** 273 * @see org.opencms.workplace.CmsWidgetDialog#getPageArray() 274 */ 275 @Override 276 protected String[] getPageArray() { 277 278 return PAGES; 279 } 280 281 /** 282 * @see org.opencms.workplace.CmsWorkplace#initMessages() 283 */ 284 @Override 285 protected void initMessages() { 286 287 // add specific dialog resource bundle 288 addMessages(Messages.get().getBundleName()); 289 // add default resource bundles 290 super.initMessages(); 291 } 292 293 /** 294 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, jakarta.servlet.http.HttpServletRequest) 295 */ 296 @Override 297 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 298 299 // set the dialog type 300 setParamDialogtype(DIALOG_TYPE); 301 302 super.initWorkplaceRequestValues(settings, request); 303 304 // save the current state of the job (may be changed because of the widget values) 305 setDialogObject(m_moduleupload); 306 } 307 308 /** 309 * Returns the list of all modules available on the server in prepared CmsSelectWidgetOption objects.<p> 310 * 311 * @return List of module names in CmsSelectWidgetOption objects 312 */ 313 private List getModulesFromServer() { 314 315 List result = new ArrayList(); 316 317 // get the systems-exportpath 318 String exportpath = OpenCms.getSystemInfo().getPackagesRfsPath(); 319 exportpath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(exportpath + "modules"); 320 File folder = new File(exportpath); 321 322 // get a list of all files 323 String[] list = folder.list(); 324 for (int i = 0; i < list.length; i++) { 325 try { 326 File diskFile = new File(exportpath, list[i]); 327 // check if it is a file and ends with zip -> this is a module 328 if (diskFile.isFile() && diskFile.getName().endsWith(".zip")) { 329 result.add(new CmsSelectWidgetOption(diskFile.getName())); 330 } else if (diskFile.isDirectory() 331 && ((new File(diskFile + File.separator + "manifest.xml")).exists())) { 332 // this is a folder with manifest file -> this a module 333 result.add(new CmsSelectWidgetOption(diskFile.getName())); 334 } 335 } catch (Throwable t) { 336 // ignore and continue 337 } 338 } 339 340 Collections.sort(result, new ComparatorSelectWidgetOption()); 341 return result; 342 } 343 344}