KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > setup > CmsUpdateBean


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/setup/CmsUpdateBean.java,v $
3  * Date : $Date: 2006/03/27 14:52:51 $
4  * Version: $Revision: 1.6 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.setup;
33
34 import org.opencms.configuration.CmsConfigurationManager;
35 import org.opencms.configuration.CmsModuleConfiguration;
36 import org.opencms.file.CmsResource;
37 import org.opencms.i18n.CmsEncoder;
38 import org.opencms.main.CmsLog;
39 import org.opencms.main.CmsSystemInfo;
40 import org.opencms.main.OpenCms;
41 import org.opencms.module.CmsModule;
42 import org.opencms.module.CmsModuleVersion;
43 import org.opencms.module.CmsModuleXmlHandler;
44 import org.opencms.report.CmsShellReport;
45 import org.opencms.report.I_CmsReport;
46 import org.opencms.util.CmsStringUtil;
47 import org.opencms.xml.CmsXmlException;
48
49 import java.io.File JavaDoc;
50 import java.io.FileInputStream JavaDoc;
51 import java.io.FileOutputStream JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.util.ArrayList JavaDoc;
54 import java.util.HashMap JavaDoc;
55 import java.util.HashSet JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.List JavaDoc;
58 import java.util.Map JavaDoc;
59 import java.util.Set JavaDoc;
60
61 import javax.servlet.jsp.JspWriter JavaDoc;
62
63 import org.apache.commons.logging.Log;
64
65 /**
66  * A java bean as a controller for the OpenCms update wizard.<p>
67  *
68  * @author Michael Moossen
69  *
70  * @version $Revision: 1.6 $
71  *
72  * @since 6.0.0
73  */

74 public class CmsUpdateBean extends CmsSetupBean {
75
76     /** name of the update folder. */
77     public static final String JavaDoc FOLDER_UPDATE = "update" + File.separatorChar;
78
79     /** replace pattern constant for the cms script. */
80     private static final String JavaDoc C_ADMIN_GROUP = "@ADMIN_GROUP@";
81
82     /** replace pattern constant for the cms script. */
83     private static final String JavaDoc C_ADMIN_PWD = "@ADMIN_PWD@";
84
85     /** replace pattern constant for the cms script. */
86     private static final String JavaDoc C_ADMIN_USER = "@ADMIN_USER@";
87
88     /** replace pattern constant for the cms script. */
89     private static final String JavaDoc C_UPDATE_PROJECT = "@UPDATE_PROJECT@";
90
91     /** replace pattern constant for the cms script. */
92     private static final String JavaDoc C_UPDATE_SITE = "@UPDATE_SITE@";
93
94     /** The static log object for this class. */
95     private static final Log LOG = CmsLog.getLog(CmsUpdateBean.class);
96
97     /** The used admin user name. */
98     private String JavaDoc m_adminGroup = "_tmpUpdateGroup" + (System.currentTimeMillis() % 1000);
99
100     /** the admin user password. */
101     private String JavaDoc m_adminPwd = "admin";
102
103     /** The used admin user name. */
104     private String JavaDoc m_adminUser = "Admin";
105
106     /** List of module to be updated. */
107     private List JavaDoc m_modulesToUpdate;
108
109     /** the update project. */
110     private String JavaDoc m_updateProject = "_tmpUpdateProject" + (System.currentTimeMillis() % 1000);
111
112     /** the site for update. */
113     private String JavaDoc m_updateSite = CmsResource.VFS_FOLDER_SITES + "/default/";
114
115     /** Cache for the up-to-date module names. */
116     private List JavaDoc m_uptodateModules;
117
118     /** The workplace import thread. */
119     private CmsUpdateThread m_workplaceUpdateThread;
120
121     /**
122      * Default constructor.<p>
123      */

124     public CmsUpdateBean() {
125
126         super();
127         m_modulesFolder = FOLDER_UPDATE + CmsSystemInfo.FOLDER_MODULES;
128         m_logFile = FOLDER_WEBINF + CmsLog.FOLDER_LOGS + "update.log";
129     }
130
131     /**
132      * Returns html code to display an error.<p>
133      *
134      * @param pathPrefix to adjust the path
135      *
136      * @return html code
137      */

138     public String JavaDoc displayError(String JavaDoc pathPrefix) {
139
140         if (pathPrefix == null) {
141             pathPrefix = "";
142         }
143         StringBuffer JavaDoc html = new StringBuffer JavaDoc(512);
144         html.append("<table border='0' cellpadding='5' cellspacing='0' style='width: 100%; height: 100%;'>");
145         html.append("\t<tr>");
146         html.append("\t\t<td style='vertical-align: middle; height: 100%;'>");
147         html.append(getHtmlPart("C_BLOCK_START", "Error"));
148         html.append("\t\t\t<table border='0' cellpadding='0' cellspacing='0' style='width: 100%;'>");
149         html.append("\t\t\t\t<tr>");
150         html.append("\t\t\t\t\t<td><img SRC='").append(pathPrefix).append("resources/error.png' border='0'></td>");
151         html.append("\t\t\t\t\t<td>&nbsp;&nbsp;</td>");
152         html.append("\t\t\t\t\t<td style='width: 100%;'>");
153         html.append("\t\t\t\t\t\tThe Alkacon OpenCms update wizard has not been started correctly!<br>");
154         html.append("\t\t\t\t\t\tPlease click <a HREF='").append(pathPrefix);
155         html.append("index.jsp'>here</a> to restart the wizard.");
156         html.append("\t\t\t\t\t</td>");
157         html.append("\t\t\t\t</tr>");
158         html.append("\t\t\t</table>");
159         html.append(getHtmlPart("C_BLOCK_END"));
160         html.append("\t\t</td>");
161         html.append("\t</tr>");
162         html.append("</table>");
163         return html.toString();
164     }
165
166     /**
167      * Returns the admin Pwd.<p>
168      *
169      * @return the admin Pwd
170      */

171     public String JavaDoc getAdminPwd() {
172
173         return m_adminPwd;
174     }
175
176     /**
177      * Returns the admin User.<p>
178      *
179      * @return the admin User
180      */

181     public String JavaDoc getAdminUser() {
182
183         return m_adminUser;
184     }
185
186     /**
187      * Returns a map of all previously installed modules.<p>
188      *
189      * @return a map of <code>[String, {@link org.opencms.module.CmsModuleVersion}]</code> objects
190      *
191      * @see org.opencms.module.CmsModuleManager#getAllInstalledModules()
192      */

193     public Map JavaDoc getInstalledModules() {
194
195         String JavaDoc file = CmsModuleConfiguration.DEFAULT_XML_FILE_NAME;
196         // /opencms/modules/module[?]
197
String JavaDoc basePath = new StringBuffer JavaDoc("/").append(CmsConfigurationManager.N_ROOT).append("/").append(
198             CmsModuleConfiguration.N_MODULES).append("/").append(CmsModuleXmlHandler.N_MODULE).append("[?]/").toString();
199         Map JavaDoc modules = new HashMap JavaDoc();
200         String JavaDoc name = "";
201         for (int i = 1; name != null; i++) {
202             if (i > 1) {
203                 String JavaDoc ver = CmsModuleVersion.DEFAULT_VERSION;
204                 try {
205                     ver = getXmlHelper().getValue(
206                         file,
207                         CmsStringUtil.substitute(basePath, "?", "" + (i - 1)) + CmsModuleXmlHandler.N_VERSION);
208                 } catch (CmsXmlException e) {
209                     // ignore
210
}
211                 modules.put(name, new CmsModuleVersion(ver));
212             }
213             try {
214                 name = getXmlHelper().getValue(
215                     file,
216                     CmsStringUtil.substitute(basePath, "?", "" + i) + CmsModuleXmlHandler.N_NAME);
217             } catch (CmsXmlException e) {
218                 // ignore
219
}
220         }
221         return modules;
222     }
223
224     /**
225      * List of modules to be updated.<p>
226      *
227      * @return a list of module names
228      */

229     public List JavaDoc getModulesToUpdate() {
230
231         if (m_modulesToUpdate == null) {
232             getUptodateModules();
233         }
234         return m_modulesToUpdate;
235     }
236
237     /**
238      * Returns the update Project.<p>
239      *
240      * @return the update Project
241      */

242     public String JavaDoc getUpdateProject() {
243
244         return m_updateProject;
245     }
246
247     /**
248      * Returns the update site.<p>
249      *
250      * @return the update site
251      */

252     public String JavaDoc getUpdateSite() {
253
254         return m_updateSite;
255     }
256
257     /**
258      * Returns the modules that does not need to be updated.<p>
259      *
260      * @return a list of module names
261      */

262     public List JavaDoc getUptodateModules() {
263
264         if (m_uptodateModules == null) {
265             m_uptodateModules = new ArrayList JavaDoc();
266             m_modulesToUpdate = new ArrayList JavaDoc();
267             Map JavaDoc installedModules = getInstalledModules();
268             Map JavaDoc availableModules = getAvailableModules();
269             Iterator JavaDoc itMods = availableModules.keySet().iterator();
270             while (itMods.hasNext()) {
271                 String JavaDoc name = (String JavaDoc)itMods.next();
272                 CmsModuleVersion instVer = (CmsModuleVersion)installedModules.get(name);
273                 CmsModuleVersion availVer = ((CmsModule)availableModules.get(name)).getVersion();
274                 boolean uptodate = (instVer != null && instVer.compareTo(availVer) >= 0);
275                 if (uptodate) {
276                     m_uptodateModules.add(name);
277                 } else {
278                     m_modulesToUpdate.add(name);
279                 }
280                 if (LOG.isDebugEnabled()) {
281                     LOG.debug(name
282                         + " --- installed: "
283                         + instVer
284                         + " available: "
285                         + availVer
286                         + " --- uptodate: "
287                         + uptodate);
288                 }
289             }
290         }
291         return m_uptodateModules;
292     }
293
294     /**
295      * Returns the workplace update thread.<p>
296      *
297      * @return the workplace update thread
298      */

299     public CmsUpdateThread getWorkplaceUpdateThread() {
300
301         return m_workplaceUpdateThread;
302     }
303
304     /**
305      * @see org.opencms.setup.CmsSetupBean#htmlModules()
306      */

307     public String JavaDoc htmlModules() {
308
309         StringBuffer JavaDoc html = new StringBuffer JavaDoc(1024);
310         Set JavaDoc uptodate = new HashSet JavaDoc(getUptodateModules());
311         Iterator JavaDoc itModules = sortModules(getAvailableModules().values()).iterator();
312         boolean hasModules = false;
313         for (int i = 0; itModules.hasNext(); i++) {
314             String JavaDoc moduleName = (String JavaDoc)itModules.next();
315             CmsModule module = (CmsModule)getAvailableModules().get(moduleName);
316             if (!uptodate.contains(moduleName)) {
317                 html.append(htmlModule(module, i));
318                 hasModules = true;
319             } else {
320                 html.append("<input type='hidden' name='availableModules' value='");
321                 html.append(moduleName);
322                 html.append("'>\n");
323             }
324         }
325         if (!hasModules) {
326             html.append("\t<tr>\n");
327             html.append("\t\t<td style='vertical-align: middle;'>\n");
328             html.append(Messages.get().getBundle().key(Messages.GUI_WARNING_ALL_MODULES_UPTODATE_0));
329             html.append("\t\t</td>\n");
330             html.append("\t</tr>\n");
331         }
332         return html.toString();
333     }
334
335     /**
336      * Creates a new instance of the setup Bean.<p>
337      *
338      * @param webAppRfsPath path to the OpenCms web application
339      * @param servletMapping the OpenCms servlet mapping
340      * @param defaultWebApplication the name of the default web application
341      *
342      */

343     public void init(String JavaDoc webAppRfsPath, String JavaDoc servletMapping, String JavaDoc defaultWebApplication) {
344
345         try {
346             super.init(webAppRfsPath, servletMapping, defaultWebApplication);
347
348             if (m_workplaceUpdateThread != null) {
349                 if (m_workplaceUpdateThread.isAlive()) {
350                     m_workplaceUpdateThread.kill();
351                 }
352                 m_workplaceUpdateThread = null;
353             }
354         } catch (Exception JavaDoc e) {
355             e.printStackTrace();
356             throw new RuntimeException JavaDoc(e);
357         }
358     }
359
360     /**
361      * Prepares step 4 of the update wizard.<p>
362      */

363     public void prepareUpdateStep5() {
364
365         if (isInitialized()) {
366             try {
367                 String JavaDoc fileName = getWebAppRfsPath() + FOLDER_UPDATE + "cmsupdate";
368                 // read the file
369
FileInputStream JavaDoc fis = new FileInputStream JavaDoc(fileName + CmsConfigurationManager.POSTFIX_ORI);
370                 String JavaDoc script = "";
371                 int readChar = fis.read();
372                 while (readChar > -1) {
373                     script += (char)readChar;
374                     readChar = fis.read();
375                 }
376                 // substitute macros
377
script = CmsStringUtil.substitute(script, C_ADMIN_USER, getAdminUser());
378                 script = CmsStringUtil.substitute(script, C_ADMIN_PWD, getAdminPwd());
379                 script = CmsStringUtil.substitute(script, C_UPDATE_PROJECT, getUpdateProject());
380                 script = CmsStringUtil.substitute(script, C_UPDATE_SITE, getUpdateSite());
381                 script = CmsStringUtil.substitute(script, C_ADMIN_GROUP, getAdminGroup());
382                 // write the new script
383
FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(fileName + ".txt");
384                 fos.write(script.getBytes());
385                 fos.close();
386             } catch (IOException JavaDoc e) {
387                 e.printStackTrace();
388                 throw new RuntimeException JavaDoc(e);
389             }
390         }
391     }
392
393     /**
394      * Prepares the update wizard.<p>
395      */

396     public void prepareUpdateStep5b() {
397
398         if (!isInitialized()) {
399             return;
400         }
401
402         if ((m_workplaceUpdateThread != null) && (m_workplaceUpdateThread.isFinished())) {
403             // update is already finished, just wait for client to collect final data
404
return;
405         }
406
407         if (m_workplaceUpdateThread == null) {
408             m_workplaceUpdateThread = new CmsUpdateThread(this);
409         }
410
411         if (!m_workplaceUpdateThread.isAlive()) {
412             m_workplaceUpdateThread.start();
413         }
414     }
415
416     /**
417      * Generates the output for the update wizard.<p>
418      *
419      * @param out the JSP print stream
420      *
421      * @throws IOException in case errors occur while writing to "out"
422      */

423     public void prepareUpdateStep5bOutput(JspWriter JavaDoc out) throws IOException JavaDoc {
424
425         m_oldLoggingOffset = m_newLoggingOffset;
426         m_newLoggingOffset = m_workplaceUpdateThread.getLoggingThread().getMessages().size();
427         if (isInitialized()) {
428             for (int i = m_oldLoggingOffset; i < m_newLoggingOffset; i++) {
429                 String JavaDoc str = m_workplaceUpdateThread.getLoggingThread().getMessages().get(i).toString();
430                 str = CmsEncoder.escapeWBlanks(str, CmsEncoder.ENCODING_UTF_8);
431                 out.println("output[" + (i - m_oldLoggingOffset) + "] = \"" + str + "\";");
432             }
433         } else {
434             out.println("output[0] = 'ERROR';");
435         }
436
437         boolean threadFinished = m_workplaceUpdateThread.isFinished();
438         boolean allWritten = m_oldLoggingOffset >= m_workplaceUpdateThread.getLoggingThread().getMessages().size();
439
440         out.println("function initThread() {");
441         if (isInitialized()) {
442             out.print("send();");
443             if (threadFinished && allWritten) {
444                 out.println("setTimeout('top.display.finish()', 500);");
445             } else {
446                 int timeout = 5000;
447                 if (getWorkplaceUpdateThread().getLoggingThread().getMessages().size() < 20) {
448                     timeout = 1000;
449                 }
450                 out.println("setTimeout('location.reload()', " + timeout + ");");
451             }
452         }
453         out.println("}");
454     }
455
456     /**
457      * Prepares step 6 of the update wizard.<p>
458      */

459     public void prepareUpdateStep6() {
460
461         if (isInitialized()) {
462             // lock the wizard for further use
463
lockWizard();
464             // save Properties to file "opencms.properties"
465
saveProperties(getProperties(), CmsSystemInfo.FILE_PROPERTIES, false);
466         }
467     }
468
469     /**
470      * Sets the admin Pwd.<p>
471      *
472      * @param adminPwd the admin Pwd to set
473      */

474     public void setAdminPwd(String JavaDoc adminPwd) {
475
476         m_adminPwd = adminPwd;
477     }
478
479     /**
480      * Sets the admin User.<p>
481      *
482      * @param adminUser the admin User to set
483      */

484     public void setAdminUser(String JavaDoc adminUser) {
485
486         m_adminUser = adminUser;
487     }
488
489     /**
490      * Sets the update Project.<p>
491      *
492      * @param updateProject the update Project to set
493      */

494     public void setUpdateProject(String JavaDoc updateProject) {
495
496         m_updateProject = updateProject;
497     }
498
499     /**
500      * Sets the update site.<p>
501      *
502      * @param site the update site to set
503      */

504     public void setUpdateSite(String JavaDoc site) {
505
506         m_updateSite = site;
507     }
508
509     /**
510      * @see org.opencms.main.I_CmsShellCommands#shellExit()
511      */

512     public void shellExit() {
513
514         System.out.println();
515         System.out.println();
516         System.out.println("The update is finished!\nThe OpenCms system used for the update will now shut down.");
517     }
518
519     /**
520      * @see org.opencms.main.I_CmsShellCommands#shellStart()
521      */

522     public void shellStart() {
523
524         System.out.println();
525         System.out.println("Starting Workplace update for OpenCms!");
526
527         String JavaDoc[] copy = org.opencms.main.Messages.COPYRIGHT_BY_ALKACON;
528         for (int i = copy.length - 1; i >= 0; i--) {
529             System.out.println(copy[i]);
530         }
531         System.out.println("This is OpenCms " + OpenCms.getSystemInfo().getVersionName());
532         System.out.println();
533         System.out.println();
534     }
535
536     /**
537      * Installed all modules that have been set using {@link #setInstallModules(String)}.<p>
538      *
539      * This method is invoked as a shell command.<p>
540      *
541      * @throws Exception if something goes wrong
542      */

543     public void updateModulesFromUpdateBean() throws Exception JavaDoc {
544
545         // read here how the list of modules to be installed is passed from the setup bean to the
546
// setup thread, and finally to the shell process that executes the setup script:
547
// 1) the list with the package names of the modules to be installed is saved by setInstallModules
548
// 2) the setup thread gets initialized in a JSP of the setup wizard
549
// 3) the instance of the setup bean is passed to the setup thread by setAdditionalShellCommand
550
// 4) the setup bean is passed to the shell by startSetup
551
// 5) because the setup bean implements I_CmsShellCommands, the shell constructor can pass the shell's CmsObject back to the setup bean
552
// 6) thus, the setup bean can do things with the Cms
553

554         if (m_cms != null && m_installModules != null) {
555             Set JavaDoc utdModules = new HashSet JavaDoc(getUptodateModules());
556             I_CmsReport report = new CmsShellReport(m_cms.getRequestContext().getLocale());
557             for (int i = 0; i < m_installModules.size(); i++) {
558                 String JavaDoc name = (String JavaDoc)m_installModules.get(i);
559                 if (!utdModules.contains(name)) {
560                     String JavaDoc filename = (String JavaDoc)m_moduleFilenames.get(name);
561                     try {
562                         updateModule(name, filename, report);
563                     } catch (Exception JavaDoc e) {
564                         // log a exception during module import, but make sure the next module is still imported
565
e.printStackTrace(System.err);
566                     }
567                 } else {
568                     report.println(
569                         Messages.get().container(Messages.RPT_MODULE_UPTODATE_1, name),
570                         I_CmsReport.FORMAT_HEADLINE);
571                 }
572             }
573         }
574     }
575
576     /**
577      * Returns the admin Group.<p>
578      *
579      * @return the admin Group
580      */

581     protected String JavaDoc getAdminGroup() {
582
583         return m_adminGroup;
584     }
585
586     /**
587      * Sets the admin Group.<p>
588      *
589      * @param adminGroup the admin Group to set
590      */

591     protected void setAdminGroup(String JavaDoc adminGroup) {
592
593         m_adminGroup = adminGroup;
594     }
595
596     /**
597      * Imports a module (zipfile) from the default module directory,
598      * creating a temporary project for this.<p>
599      *
600      * @param moduleName the name of the module to replace
601      * @param importFile the name of the import .zip file located in the update module directory
602      * @param report the shell report to write the output
603      *
604      * @throws Exception if something goes wrong
605      *
606      * @see org.opencms.importexport.CmsImportExportManager#importData(org.opencms.file.CmsObject, String, String, org.opencms.report.I_CmsReport)
607      */

608     protected void updateModule(String JavaDoc moduleName, String JavaDoc importFile, I_CmsReport report) throws Exception JavaDoc {
609
610         String JavaDoc fileName = getModuleFolder() + importFile;
611
612         report.println(
613             Messages.get().container(Messages.RPT_BEGIN_UPDATE_MODULE_1, moduleName),
614             I_CmsReport.FORMAT_HEADLINE);
615         if (OpenCms.getModuleManager().getModule(moduleName) != null) {
616             OpenCms.getModuleManager().deleteModule(m_cms, moduleName, true, report);
617         }
618         OpenCms.getImportExportManager().importData(m_cms, fileName, null, report);
619         report.println(
620             Messages.get().container(Messages.RPT_END_UPDATE_MODULE_1, moduleName),
621             I_CmsReport.FORMAT_HEADLINE);
622     }
623
624 }
Popular Tags