Source Code Cross Referenced for PortletApplicationManager.java in  » Portal » jetspeed-2.1.3 » org » apache » jetspeed » tools » pamanager » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » jetspeed 2.1.3 » org.apache.jetspeed.tools.pamanager 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.jetspeed.tools.pamanager;
0018:
0019:        import java.io.File;
0020:        import java.io.IOException;
0021:        import java.security.Permission;
0022:        import java.util.ArrayList;
0023:        import java.util.Collection;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:
0027:        import org.apache.commons.logging.Log;
0028:        import org.apache.commons.logging.LogFactory;
0029:        import org.apache.jetspeed.cluster.NodeManager;
0030:        import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
0031:        import org.apache.jetspeed.components.portletentity.PortletEntityNotDeletedException;
0032:        import org.apache.jetspeed.components.portletregistry.PortletRegistry;
0033:        import org.apache.jetspeed.components.portletregistry.RegistryException;
0034:        import org.apache.jetspeed.container.window.PortletWindowAccessor;
0035:        import org.apache.jetspeed.factory.PortletFactory;
0036:        import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
0037:        import org.apache.jetspeed.om.common.servlet.MutableWebApplication;
0038:        import org.apache.jetspeed.search.SearchEngine;
0039:        import org.apache.jetspeed.security.PermissionManager;
0040:        import org.apache.jetspeed.security.PortletPermission;
0041:        import org.apache.jetspeed.security.Role;
0042:        import org.apache.jetspeed.security.RoleManager;
0043:        import org.apache.jetspeed.security.SecurityException;
0044:        import org.apache.jetspeed.util.DirectoryHelper;
0045:        import org.apache.jetspeed.util.FileSystemHelper;
0046:        import org.apache.jetspeed.util.MultiFileChecksumHelper;
0047:        import org.apache.jetspeed.util.descriptor.PortletApplicationWar;
0048:        import org.apache.pluto.om.common.SecurityRole;
0049:        import org.apache.pluto.om.entity.PortletEntity;
0050:        import org.apache.pluto.om.entity.PortletEntityCtrl;
0051:        import org.apache.pluto.om.portlet.PortletDefinition;
0052:
0053:        /**
0054:         * PortletApplicationManager
0055:         *
0056:         * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
0057:         * @version $Id: PortletApplicationManager.java,v 1.21 2005/04/09 00:24:44 shinsuke Exp $
0058:         */
0059:        public class PortletApplicationManager implements 
0060:                PortletApplicationManagement {
0061:            private static int DEFAULT_DESCRIPTOR_CHANGE_MONITOR_INTERVAL = 10 * 1000; // 10 seconds
0062:            private static int DEFAULT_MAX_RETRIED_STARTS = 10; // 10 times retry PA
0063:            private static final Log log = LogFactory.getLog("deployment");
0064:
0065:            protected PortletEntityAccessComponent entityAccess;
0066:            protected PortletFactory portletFactory;
0067:            protected PortletRegistry registry;
0068:            protected PortletWindowAccessor windowAccess;
0069:            protected SearchEngine searchEngine;
0070:            protected RoleManager roleManager;
0071:            protected PermissionManager permissionManager;
0072:            protected boolean autoCreateRoles;
0073:            protected List permissionRoles;
0074:            protected int descriptorChangeMonitorInterval = DEFAULT_DESCRIPTOR_CHANGE_MONITOR_INTERVAL;
0075:            /**
0076:             * holds the max number of retries in case of unsuccessful PA start
0077:             * this addresses possible startup errors in clustered environments
0078:             */
0079:            protected int maxRetriedStarts = DEFAULT_MAX_RETRIED_STARTS;
0080:            protected DescriptorChangeMonitor monitor;
0081:            protected boolean started;
0082:            protected String appRoot;
0083:            protected NodeManager nodeManager;
0084:
0085:            /**
0086:             * Creates a new PortletApplicationManager object.
0087:             */
0088:            public PortletApplicationManager(PortletFactory portletFactory,
0089:                    PortletRegistry registry,
0090:                    PortletEntityAccessComponent entityAccess,
0091:                    PortletWindowAccessor windowAccess,
0092:                    PermissionManager permissionManager,
0093:                    SearchEngine searchEngine, RoleManager roleManager,
0094:                    List permissionRoles, NodeManager nodeManager,
0095:                    String appRoot) {
0096:                this .portletFactory = portletFactory;
0097:                this .registry = registry;
0098:                this .entityAccess = entityAccess;
0099:                this .windowAccess = windowAccess;
0100:                this .permissionManager = permissionManager;
0101:                this .searchEngine = searchEngine;
0102:                this .roleManager = roleManager;
0103:                this .permissionRoles = permissionRoles;
0104:                this .nodeManager = nodeManager;
0105:                this .appRoot = appRoot;
0106:            }
0107:
0108:            public void start() {
0109:                if (descriptorChangeMonitorInterval > 0) {
0110:                    try {
0111:                        monitor = new DescriptorChangeMonitor(
0112:                                Thread.currentThread().getThreadGroup(),
0113:                                "PortletApplicationManager Descriptor Change Monitor Thread",
0114:                                this , descriptorChangeMonitorInterval,
0115:                                maxRetriedStarts);
0116:
0117:                        monitor.setContextClassLoader(getClass()
0118:                                .getClassLoader());
0119:                        monitor.start();
0120:                        log
0121:                                .info("PortletApplicationManager Descriptor Change Monitor started!");
0122:                    } catch (Exception e) {
0123:                        log.warn(
0124:                                "Unable to start PortletApplicationManager Descriptor Change Monitor: "
0125:                                        + e.toString(), e);
0126:                        monitor.safeStop();
0127:                        monitor = null;
0128:                    }
0129:                }
0130:                started = true;
0131:            }
0132:
0133:            public void stop() {
0134:                started = false;
0135:                if (monitor != null) {
0136:                    monitor.safeStop();
0137:                    monitor = null;
0138:                }
0139:            }
0140:
0141:            public boolean isStarted() {
0142:                return started;
0143:            }
0144:
0145:            public void setRoleManager(RoleManager roleManager) {
0146:                this .roleManager = roleManager;
0147:            }
0148:
0149:            public void setAutoCreateRoles(boolean autoCreateRoles) {
0150:                this .autoCreateRoles = autoCreateRoles;
0151:            }
0152:
0153:            public void setSearchEngine(SearchEngine searchEngine) {
0154:                this .searchEngine = searchEngine;
0155:            }
0156:
0157:            private void checkStarted() {
0158:                if (!started) {
0159:                    throw new IllegalStateException("Not started yet");
0160:                }
0161:            }
0162:
0163:            public void startLocalPortletApplication(String contextName,
0164:                    FileSystemHelper warStruct, ClassLoader paClassLoader)
0165:                    throws RegistryException {
0166:                checkStarted();
0167:                startPA(contextName, "/" + contextName, warStruct,
0168:                        paClassLoader, MutablePortletApplication.LOCAL);
0169:            }
0170:
0171:            public void startInternalApplication(String contextName)
0172:                    throws RegistryException {
0173:                checkStarted();
0174:                File webinf = new File(appRoot);
0175:                ClassLoader contextClassLoader = Thread.currentThread()
0176:                        .getContextClassLoader();
0177:                DirectoryHelper dir = new DirectoryHelper(webinf);
0178:                String appName = (contextName.startsWith("/")) ? contextName
0179:                        .substring(1) : contextName;
0180:                MutablePortletApplication app = registry
0181:                        .getPortletApplicationByIdentifier(appName);
0182:                if (app != null
0183:                        && app.getApplicationType() == MutablePortletApplication.LOCAL) {
0184:                    app.setApplicationType(MutablePortletApplication.INTERNAL);
0185:                    registry.updatePortletApplication(app);
0186:                }
0187:                startPA(contextName, "/" + contextName, dir,
0188:                        contextClassLoader, MutablePortletApplication.INTERNAL);
0189:                // startInternal(contextName, warStruct, paClassLoader, true);        
0190:            }
0191:
0192:            public void startPortletApplication(String contextName,
0193:                    FileSystemHelper warStruct, ClassLoader paClassLoader)
0194:                    throws RegistryException {
0195:                startPortletApplication(contextName, "/" + contextName,
0196:                        warStruct, paClassLoader);
0197:            }
0198:
0199:            public void startPortletApplication(String contextName,
0200:                    String contextPath, FileSystemHelper warStruct,
0201:                    ClassLoader paClassLoader) throws RegistryException {
0202:                checkStarted();
0203:                ClassLoader contextClassLoader = Thread.currentThread()
0204:                        .getContextClassLoader();
0205:                Thread.currentThread().setContextClassLoader(
0206:                        this .getClass().getClassLoader());
0207:                try {
0208:                    startPA(contextName, contextPath, warStruct, paClassLoader,
0209:                            MutablePortletApplication.WEBAPP);
0210:                } finally {
0211:                    Thread.currentThread().setContextClassLoader(
0212:                            contextClassLoader);
0213:                }
0214:
0215:            }
0216:
0217:            public void stopLocalPortletApplication(String contextName)
0218:                    throws RegistryException {
0219:                stopPA(contextName, MutablePortletApplication.LOCAL);
0220:            }
0221:
0222:            public void stopPortletApplication(String contextName)
0223:                    throws RegistryException {
0224:                ClassLoader contextClassLoader = Thread.currentThread()
0225:                        .getContextClassLoader();
0226:                Thread.currentThread().setContextClassLoader(
0227:                        this .getClass().getClassLoader());
0228:                try {
0229:                    stopPA(contextName, MutablePortletApplication.WEBAPP);
0230:                } finally {
0231:                    Thread.currentThread().setContextClassLoader(
0232:                            contextClassLoader);
0233:                }
0234:            }
0235:
0236:            public void unregisterPortletApplication(String paName)
0237:                    throws RegistryException {
0238:                ClassLoader contextClassLoader = Thread.currentThread()
0239:                        .getContextClassLoader();
0240:                Thread.currentThread().setContextClassLoader(
0241:                        this .getClass().getClassLoader());
0242:                try {
0243:                    MutablePortletApplication pa = null;
0244:
0245:                    try {
0246:                        pa = registry.getPortletApplication(paName);
0247:                    } catch (Exception e) {
0248:                        // ignore errors during portal shutdown
0249:                    }
0250:
0251:                    if (pa != null) {
0252:                        if (portletFactory.isPortletApplicationRegistered(pa)) {
0253:                            throw new RegistryException("Portlet Application "
0254:                                    + paName + " still running");
0255:                        }
0256:
0257:                        unregisterPortletApplication(pa, true);
0258:                        try {
0259:                            nodeManager.removeNode(paName);
0260:                        } catch (Exception ee) {
0261:                            // we actually do not care about an exception in the remove operation...
0262:                        }
0263:                    }
0264:                } finally {
0265:                    Thread.currentThread().setContextClassLoader(
0266:                            contextClassLoader);
0267:                }
0268:            }
0269:
0270:            protected void checkValidContextName(String contextName,
0271:                    boolean local) throws RegistryException {
0272:                int prefixLength = LOCAL_PA_PREFIX.length();
0273:
0274:                if ((contextName.length() >= prefixLength)
0275:                        && contextName.substring(0, prefixLength)
0276:                                .equalsIgnoreCase(LOCAL_PA_PREFIX)) {
0277:                    if (!local) {
0278:                        throw new RegistryException(
0279:                                "Prefix \""
0280:                                        + LOCAL_PA_PREFIX
0281:                                        + "\" is reserved for Local Portlet Applications only.");
0282:                    }
0283:                } else if (local) {
0284:                    throw new RegistryException("Prefix \"" + LOCAL_PA_PREFIX
0285:                            + "\" is required for Local Portlet Applications.");
0286:                }
0287:            }
0288:
0289:            protected MutablePortletApplication registerPortletApplication(
0290:                    PortletApplicationWar paWar,
0291:                    MutablePortletApplication oldPA, int paType,
0292:                    ClassLoader paClassLoader) throws RegistryException {
0293:                if (oldPA != null) {
0294:                    unregisterPortletApplication(oldPA, false);
0295:                    oldPA = null;
0296:                }
0297:
0298:                MutablePortletApplication pa = null;
0299:                boolean registered = false;
0300:                String paName = paWar.getPortletApplicationName();
0301:
0302:                try {
0303:                    log.info("Loading portlet.xml...." + paName);
0304:                    pa = paWar.createPortletApp(paClassLoader);
0305:                    pa.setApplicationType(paType);
0306:
0307:                    // load the web.xml
0308:                    log.info("Loading web.xml...." + paName);
0309:                    MutableWebApplication wa = paWar.createWebApp();
0310:                    paWar.validate();
0311:
0312:                    if (paType == MutablePortletApplication.LOCAL) {
0313:                        wa.setContextRoot("<portal>");
0314:                    } else if (paType == MutablePortletApplication.INTERNAL) {
0315:                        // TODO: this is screwing up the PSML as its set all over the place to "jetspeed-layouts", not good
0316:                        wa.setContextRoot("/" + paName);
0317:                    }
0318:
0319:                    pa.setWebApplicationDefinition(wa);
0320:
0321:                    // Make sure existing entities are refreshed with the most
0322:                    // recent PortletDefintion.
0323:                    Collection portletDefs = pa.getPortletDefinitions();
0324:                    if (portletDefs != null && portletDefs.size() > 0) {
0325:                        Iterator pdItr = portletDefs.iterator();
0326:                        while (pdItr.hasNext()) {
0327:                            PortletDefinition pd = (PortletDefinition) pdItr
0328:                                    .next();
0329:                            Collection portletEntites = entityAccess
0330:                                    .getPortletEntities(pd);
0331:                            if (portletEntites != null
0332:                                    && portletEntites.size() > 0) {
0333:                                Iterator peItr = portletEntites.iterator();
0334:                                while (peItr.hasNext()) {
0335:                                    PortletEntityCtrl portletEntity = (PortletEntityCtrl) peItr
0336:                                            .next();
0337:                                    portletEntity.setPortletDefinition(pd);
0338:                                }
0339:                            }
0340:                        }
0341:                    }
0342:                } catch (Exception e) {
0343:                    String msg = "Failed to load portlet application for "
0344:                            + paWar.getPortletApplicationName();
0345:                    log.error(msg, e);
0346:                    throw new RegistryException(msg);
0347:                }
0348:
0349:                // register the portlet application
0350:                try {
0351:                    registry.registerPortletApplication(pa);
0352:                    registered = true;
0353:                    log.info("Registered the portlet application " + paName);
0354:
0355:                    // add to search engine result
0356:                    this .updateSearchEngine(false, pa);
0357:
0358:                    // and add to the current node info
0359:                    nodeManager.addNode(new Long(pa.getId().toString()), pa
0360:                            .getName());
0361:
0362:                    // grant default permissions to portlet application
0363:                    grantDefaultPermissions(paName);
0364:
0365:                    if (autoCreateRoles
0366:                            && roleManager != null
0367:                            && pa.getWebApplicationDefinition()
0368:                                    .getSecurityRoles() != null) {
0369:                        try {
0370:                            Iterator rolesIter = pa
0371:                                    .getWebApplicationDefinition()
0372:                                    .getSecurityRoles().iterator();
0373:                            SecurityRole sr;
0374:                            while (rolesIter.hasNext()) {
0375:                                sr = (SecurityRole) rolesIter.next();
0376:                                if (!roleManager.roleExists(sr.getRoleName())) {
0377:                                    roleManager.addRole(sr.getRoleName());
0378:                                    log.info("AutoCreated role: "
0379:                                            + sr.getRoleName()
0380:                                            + " from portlet application "
0381:                                            + paName + " its web definition");
0382:                                }
0383:                            }
0384:                        } catch (SecurityException sex) {
0385:                            log.warn(
0386:                                    "Failed to autoCreate roles for portlet application "
0387:                                            + paName + ": " + sex.getMessage(),
0388:                                    sex);
0389:                        }
0390:                    }
0391:
0392:                    return pa;
0393:                } catch (Exception e) {
0394:                    String msg = "Failed to register portlet application, "
0395:                            + paName;
0396:                    log.error(msg, e);
0397:
0398:                    if (registered) {
0399:                        try {
0400:                            unregisterPortletApplication(pa,
0401:                                    (paType == MutablePortletApplication.LOCAL));
0402:                        } catch (Exception re) {
0403:                            log.error(
0404:                                    "Failed to rollback registration of portlet application "
0405:                                            + paName, re);
0406:                        }
0407:                    }
0408:
0409:                    throw new RegistryException(msg, e);
0410:                }
0411:            }
0412:
0413:            protected void startPA(String contextName, String contextPath,
0414:                    FileSystemHelper warStruct, ClassLoader paClassLoader,
0415:                    int paType) throws RegistryException {
0416:                startPA(contextName, contextPath, warStruct, paClassLoader,
0417:                        paType, 0);
0418:            }
0419:
0420:            protected void startPA(String contextName, String contextPath,
0421:                    FileSystemHelper warStruct, ClassLoader paClassLoader,
0422:                    int paType, long checksum) throws RegistryException {
0423:                boolean register = true;
0424:                boolean monitored = false;
0425:                DescriptorChangeMonitor changeMonitor = this .monitor;
0426:                if (changeMonitor != null) {
0427:                    monitored = changeMonitor.isMonitored(contextName);
0428:                }
0429:                if (log.isDebugEnabled()) {
0430:                    log.debug("Is portlet application " + contextName
0431:                            + " monitored? -> " + monitored);
0432:                }
0433:                PortletApplicationWar paWar = null;
0434:                try {
0435:                    if (log.isDebugEnabled()) {
0436:                        log.debug("Try to start portlet application "
0437:                                + contextName + ".");
0438:                    }
0439:                    // create PA  from war (file) structure
0440:                    // paWar = new PortletApplicationWar(warStruct, contextName, "/" + contextName, checksum);
0441:                    paWar = new PortletApplicationWar(warStruct, contextName,
0442:                            contextPath, checksum);
0443:                    try {
0444:                        if (paClassLoader == null) {
0445:                            paClassLoader = paWar.createClassloader(getClass()
0446:                                    .getClassLoader());
0447:                        }
0448:                        // create checksum from PA descriptors
0449:                        checksum = paWar.getPortletApplicationChecksum();
0450:
0451:                        if (log.isDebugEnabled()) {
0452:                            log.debug("New checksum for portlet application "
0453:                                    + contextName + " is " + checksum);
0454:                        }
0455:                    } catch (IOException e) {
0456:                        String msg = "Invalid PA WAR for " + contextName;
0457:                        log.error(msg, e);
0458:                        if (paClassLoader == null) {
0459:                            // nothing to be done about it anymore: this pa is beyond repair :(
0460:                            throw new RegistryException(e);
0461:                        }
0462:                        register = false;
0463:                    }
0464:
0465:                    // try to get the PA from database by context name
0466:                    MutablePortletApplication pa = registry
0467:                            .getPortletApplication(contextName);
0468:
0469:                    if (pa != null) {
0470:                        if (log.isDebugEnabled()) {
0471:                            log.debug("Portlet Application " + contextName
0472:                                    + " found in registry.");
0473:                        }
0474:                        if (pa.getApplicationType() != paType) {
0475:                            throw new RegistryException(
0476:                                    "Cannot start portlet application "
0477:                                            + contextName
0478:                                            + ": as Application Types don't match: "
0479:                                            + pa.getApplicationType() + " != "
0480:                                            + paType);
0481:                        }
0482:                        if (!monitored && changeMonitor != null) {
0483:                            changeMonitor.remove(contextName);
0484:                        }
0485:                        if (log.isDebugEnabled()) {
0486:                            log.debug("unregistering portlet application "
0487:                                    + contextName + "...");
0488:                        }
0489:                        portletFactory.unregisterPortletApplication(pa);
0490:                    }
0491:                    //            if (register && (pa == null || checksum != pa.getChecksum()))
0492:                    if (register) {
0493:                        if (pa == null) {
0494:                            // new
0495:                            try {
0496:                                if (log.isDebugEnabled()) {
0497:                                    log
0498:                                            .debug("Register new portlet application "
0499:                                                    + contextName + ".");
0500:                                }
0501:                                pa = registerPortletApplication(paWar, pa,
0502:                                        paType, paClassLoader);
0503:                            } catch (Exception e) {
0504:                                String msg = "Error register new portlet application "
0505:                                        + contextName + ".";
0506:
0507:                                if (log.isDebugEnabled()) {
0508:                                    log.debug(msg);
0509:                                }
0510:                                throw new RegistryException(msg);
0511:
0512:                            }
0513:                        } else {
0514:                            if (log.isDebugEnabled()) {
0515:                                log
0516:                                        .debug("Re-register existing portlet application "
0517:                                                + contextName + ".");
0518:                            }
0519:                            int status = nodeManager.checkNode(new Long(pa
0520:                                    .getId().toString()), pa.getName());
0521:                            boolean reregister = false;
0522:                            boolean deploy = false;
0523:                            switch (status) {
0524:                            case NodeManager.NODE_NEW: {
0525:                                if (log.isDebugEnabled()) {
0526:                                    log.debug("Node for Portlet application "
0527:                                            + contextName + " is NEW.");
0528:                                }
0529:                                //only reason is that the file got somehow corrupted 
0530:                                // so we really do not know what is going on here...
0531:                                // the best chance at this point is to reregister (which might be the absolute wrong choice)
0532:                                log
0533:                                        .warn("The portlet application "
0534:                                                + pa.getName()
0535:                                                + " is registered in the database but not locally .... we will reregister");
0536:                                reregister = true;
0537:                                if (checksum != pa.getChecksum()) {
0538:                                    log
0539:                                            .warn("The provided portlet application "
0540:                                                    + pa.getName()
0541:                                                    + " is a different version than in the database (db-checksum="
0542:                                                    + pa.getChecksum()
0543:                                                    + ", local-checksum=: "
0544:                                                    + checksum
0545:                                                    + ") .... we will redeploy (also to the database)");
0546:                                    deploy = true;
0547:                                }
0548:                                break;
0549:                            }
0550:                            case NodeManager.NODE_SAVED: {
0551:                                if (log.isDebugEnabled()) {
0552:                                    log.debug("Node for Portlet application "
0553:                                            + contextName + " is SAVED.");
0554:                                }
0555:                                if (checksum != pa.getChecksum()) {
0556:                                    log
0557:                                            .warn("The provided portlet application "
0558:                                                    + pa.getName()
0559:                                                    + " is a different version than in the local node info and the database (db-checksum="
0560:                                                    + pa.getChecksum()
0561:                                                    + ", local-checksum=: "
0562:                                                    + checksum
0563:                                                    + ") .... we will reregister AND redeploy (also to the database)");
0564:                                    //database and local node info are in synch, so we assume that this is a brand new
0565:                                    // war .... let's deploy
0566:                                    reregister = true;
0567:                                    deploy = true;
0568:                                }
0569:                                break;
0570:                            }
0571:                            case NodeManager.NODE_OUTDATED: {
0572:                                // new version in database, maybe changed by a different cluster node
0573:                                if (log.isDebugEnabled()) {
0574:                                    log
0575:                                            .debug("Node for Portlet application "
0576:                                                    + contextName
0577:                                                    + " is OUTDATED (local PA.id < DB PA.id).");
0578:                                }
0579:                                //database version is older (determined by id) than the database 
0580:                                //let's deploy and reregister
0581:                                if (checksum != pa.getChecksum()) {
0582:                                    log
0583:                                            .error("The portlet application "
0584:                                                    + pa.getName()
0585:                                                    + " provided for the upgrade IS WRONG. The database checksum= "
0586:                                                    + pa.getChecksum()
0587:                                                    + ", but the local="
0588:                                                    + checksum
0589:                                                    + "....THIS NEEDS TO BE CORRECTED");
0590:                                    // if the checksums do not match make sure the database is updated with the new PA from file system
0591:                                    // I've observed "unavailable PA" in clustered env for the cluster node that reported OUTDATED state
0592:                                    deploy = true;
0593:                                }
0594:                                reregister = true;
0595:                                break;
0596:                            }
0597:                            }
0598:                            if (deploy) {
0599:                                if (log.isDebugEnabled()) {
0600:                                    log
0601:                                            .debug("Register (deploy=true) Portlet application "
0602:                                                    + contextName
0603:                                                    + " in database.");
0604:                                }
0605:                                pa = registerPortletApplication(paWar, pa,
0606:                                        paType, paClassLoader);
0607:                            } else if (reregister) {
0608:                                if (log.isDebugEnabled()) {
0609:                                    log
0610:                                            .debug("Re-Register (reregister=true) Portlet application "
0611:                                                    + contextName + ".");
0612:                                }
0613:                                // add to search engine result
0614:                                this .updateSearchEngine(true, pa);
0615:                                this .updateSearchEngine(false, pa);
0616:
0617:                                // and add to the current node info
0618:                                try {
0619:                                    nodeManager.addNode(new Long(pa.getId()
0620:                                            .toString()), pa.getName());
0621:                                } catch (Exception e) {
0622:                                    log.error(
0623:                                            "Adding node for portlet application "
0624:                                                    + pa.getName()
0625:                                                    + " caused exception", e);
0626:                                }
0627:                            }
0628:
0629:                        }
0630:                    }
0631:                    if (register) {
0632:                        if (log.isDebugEnabled()) {
0633:                            log.debug("Register Portlet application "
0634:                                    + contextName + " in portlet factory.");
0635:                        }
0636:                        portletFactory.registerPortletApplication(pa,
0637:                                paClassLoader);
0638:                    }
0639:
0640:                    if (!monitored && changeMonitor != null) {
0641:                        if (log.isDebugEnabled()) {
0642:                            log.debug("Add change monitor for application "
0643:                                    + contextName + " with checksum "
0644:                                    + checksum + ".");
0645:                        }
0646:                        changeMonitor.monitor(contextName, contextPath,
0647:                                paClassLoader, paType, warStruct
0648:                                        .getRootDirectory(), checksum);
0649:                    }
0650:                } catch (Exception e) {
0651:                    String msg = "Error starting portlet application "
0652:                            + contextName;
0653:
0654:                    log.error(msg, e);
0655:                    // monitor PA for changes
0656:                    // do not add monitor if a monitor already exists
0657:                    if (!monitored && changeMonitor != null) {
0658:                        // this code should be hit only during startup process
0659:                        if (log.isDebugEnabled()) {
0660:                            log.debug("Add change monitor for application "
0661:                                    + contextName
0662:                                    + " and set unsuccessful starts to 1.");
0663:                        }
0664:                        changeMonitor.monitor(contextName, contextPath,
0665:                                paClassLoader, paType, warStruct
0666:                                        .getRootDirectory(), checksum);
0667:                        changeMonitor.get(contextName).setUnsuccessfulStarts(1);
0668:                    }
0669:                    throw new RegistryException(msg);
0670:                } finally {
0671:                    if (paWar != null) {
0672:                        try {
0673:                            paWar.close();
0674:                        } catch (IOException e) {
0675:                            log.error("Failed to close PA WAR for "
0676:                                    + contextName, e);
0677:                        }
0678:                    }
0679:                }
0680:            }
0681:
0682:            protected void stopPA(String contextName, int paType)
0683:                    throws RegistryException {
0684:                MutablePortletApplication pa = null;
0685:
0686:                try {
0687:                    pa = registry.getPortletApplication(contextName);
0688:                } catch (Exception e) {
0689:                    // ignore errors during portal shutdown
0690:                }
0691:                if (pa != null && pa.getApplicationType() != paType) {
0692:                    throw new RegistryException(
0693:                            "Cannot stop portlet application " + contextName
0694:                                    + ": as Application Types don't match: "
0695:                                    + pa.getApplicationType() + " != " + paType);
0696:                }
0697:                DescriptorChangeMonitor monitor = this .monitor;
0698:                if (monitor != null) {
0699:                    monitor.remove(contextName);
0700:                }
0701:                if (pa != null) {
0702:                    portletFactory.unregisterPortletApplication(pa);
0703:                }
0704:            }
0705:
0706:            protected void updateSearchEngine(boolean remove,
0707:                    MutablePortletApplication pa) {
0708:                if (searchEngine != null) {
0709:                    if (remove) {
0710:                        searchEngine.remove(pa);
0711:                        searchEngine.remove(pa.getPortletDefinitions());
0712:                        log
0713:                                .info("Un-Registered the portlet application in the search engine... "
0714:                                        + pa.getName());
0715:                    } else {
0716:                        searchEngine.add(pa);
0717:                        searchEngine.add(pa.getPortletDefinitions());
0718:                        log
0719:                                .info("Registered the portlet application in the search engine... "
0720:                                        + pa.getName());
0721:                    }
0722:                }
0723:
0724:            }
0725:
0726:            protected void unregisterPortletApplication(
0727:                    MutablePortletApplication pa, boolean purgeEntityInfo)
0728:                    throws RegistryException {
0729:
0730:                updateSearchEngine(true, pa);
0731:                log
0732:                        .info("Remove all registry entries defined for portlet application "
0733:                                + pa.getName());
0734:
0735:                Iterator portlets = pa.getPortletDefinitions().iterator();
0736:
0737:                while (portlets.hasNext()) {
0738:                    PortletDefinition portletDefinition = (PortletDefinition) portlets
0739:                            .next();
0740:                    Iterator entities = entityAccess.getPortletEntities(
0741:                            portletDefinition).iterator();
0742:
0743:                    while (entities.hasNext()) {
0744:                        PortletEntity entity = (PortletEntity) entities.next();
0745:
0746:                        if (purgeEntityInfo) {
0747:                            try {
0748:                                entityAccess.removePortletEntity(entity);
0749:                            } catch (PortletEntityNotDeletedException e) {
0750:                                String msg = "Failed to delete Portlet Entity "
0751:                                        + entity.getId();
0752:                                log.error(msg, e);
0753:                                throw new RegistryException(msg, e);
0754:                            }
0755:                        }
0756:
0757:                        entityAccess.removeFromCache(entity);
0758:                        windowAccess.removeWindows(entity);
0759:                    }
0760:                }
0761:
0762:                // todo keep (User)Prefs?
0763:                registry.removeApplication(pa);
0764:                revokeDefaultPermissions(pa.getName());
0765:            }
0766:
0767:            protected void grantDefaultPermissions(String paName) {
0768:                try {
0769:                    // create a default permission for this portlet app, granting configured roles to the portlet application 
0770:                    Iterator roles = permissionRoles.iterator();
0771:                    while (roles.hasNext()) {
0772:                        String roleName = (String) roles.next();
0773:                        Role userRole = roleManager.getRole(roleName);
0774:                        if (userRole != null) {
0775:                            Permission permission = new PortletPermission(
0776:                                    paName + "::*", "view, edit");
0777:                            if (!permissionManager.permissionExists(permission)) {
0778:                                permissionManager.addPermission(permission);
0779:                                permissionManager.grantPermission(userRole
0780:                                        .getPrincipal(), permission);
0781:                            }
0782:                        }
0783:                    }
0784:                } catch (SecurityException e) {
0785:                    log.error("Error granting default permissions for "
0786:                            + paName, e);
0787:                }
0788:            }
0789:
0790:            protected void revokeDefaultPermissions(String paName) {
0791:                try {
0792:                    Iterator roles = permissionRoles.iterator();
0793:                    while (roles.hasNext()) {
0794:                        String roleName = (String) roles.next();
0795:                        Role userRole = roleManager.getRole(roleName);
0796:                        if (userRole != null) {
0797:                            Permission permission = new PortletPermission(
0798:                                    paName + "::*", "view, edit");
0799:                            if (permissionManager.permissionExists(permission)) {
0800:                                permissionManager.removePermission(permission);
0801:                            }
0802:
0803:                        }
0804:                    }
0805:                } catch (SecurityException e) {
0806:                    log.error("Error revoking default permissions for "
0807:                            + paName, e);
0808:                }
0809:            }
0810:
0811:            public int getDescriptorChangeMonitorInterval() {
0812:                return descriptorChangeMonitorInterval / 1000;
0813:            }
0814:
0815:            public void setDescriptorChangeMonitorInterval(
0816:                    int descriptorChangeMonitorInterval) {
0817:                this .descriptorChangeMonitorInterval = descriptorChangeMonitorInterval * 1000;
0818:            }
0819:
0820:            private static class DescriptorChangeMonitor extends Thread {
0821:                private static class DescriptorChangeMonitorInfo {
0822:                    private String contextName;
0823:                    private String contextPath;
0824:                    private ClassLoader paClassLoader;
0825:                    private int paType;
0826:                    private File paDir;
0827:                    private File[] descriptors;
0828:                    private long descriptorModificationTime;
0829:                    private long extendedDescriptorModificationTime;
0830:                    private long checksum;
0831:                    private boolean obsolete;
0832:
0833:                    /**
0834:                     * holds the number of unsuccessful starts of the monitored PA
0835:                     */
0836:                    private int unsuccessfulStarts;
0837:
0838:                    /*
0839:                     * Constructor only used for looking up the matching registered one in monitorsInfo
0840:                     */
0841:                    public DescriptorChangeMonitorInfo(String contextName) {
0842:                        this .contextName = contextName;
0843:                    }
0844:
0845:                    public DescriptorChangeMonitorInfo(String contextName,
0846:                            String contextPath, ClassLoader paClassLoader,
0847:                            int paType, File paDir, long checksum) {
0848:                        this .contextName = contextName;
0849:                        this .contextPath = contextPath;
0850:                        this .paClassLoader = paClassLoader;
0851:                        this .paType = paType;
0852:                        this .paDir = paDir.isAbsolute() ? paDir : paDir
0853:                                .getAbsoluteFile();
0854:                        this .checksum = checksum;
0855:
0856:                        this .descriptors = new File[] {
0857:                                new File(paDir,
0858:                                        PortletApplicationWar.WEB_XML_PATH),
0859:                                new File(paDir,
0860:                                        PortletApplicationWar.PORTLET_XML_PATH),
0861:                                new File(
0862:                                        paDir,
0863:                                        PortletApplicationWar.EXTENDED_PORTLET_XML_PATH) };
0864:
0865:                        descriptorModificationTime = descriptors[1]
0866:                                .lastModified();
0867:                        extendedDescriptorModificationTime = descriptors[2]
0868:                                .lastModified();
0869:                    }
0870:
0871:                    public String getContextName() {
0872:                        return contextName;
0873:                    }
0874:
0875:                    public ClassLoader getPAClassLoader() {
0876:                        return paClassLoader;
0877:                    }
0878:
0879:                    public int getPortletApplicationType() {
0880:                        return paType;
0881:                    }
0882:
0883:                    public File getPADir() {
0884:                        return paDir;
0885:                    }
0886:
0887:                    public long getChecksum() {
0888:                        return checksum;
0889:                    }
0890:
0891:                    public boolean isChanged() {
0892:                        if (!obsolete) {
0893:                            long newDescriptorModificationTime = descriptors[1]
0894:                                    .lastModified();
0895:                            long newExtendedDescriptorModificationTime = descriptors[2]
0896:                                    .lastModified();
0897:                            if (descriptorModificationTime != newDescriptorModificationTime
0898:                                    || extendedDescriptorModificationTime != newExtendedDescriptorModificationTime) {
0899:                                descriptorModificationTime = newDescriptorModificationTime;
0900:                                extendedDescriptorModificationTime = newExtendedDescriptorModificationTime;
0901:                                long newChecksum = MultiFileChecksumHelper
0902:                                        .getChecksum(descriptors);
0903:                                if (log.isDebugEnabled()) {
0904:                                    log
0905:                                            .debug("checksum check for descriptors for application "
0906:                                                    + contextName
0907:                                                    + ": old ("
0908:                                                    + checksum
0909:                                                    + ") new ("
0910:                                                    + newChecksum + ").");
0911:                                }
0912:                                if (checksum != newChecksum) {
0913:                                    if (log.isDebugEnabled()) {
0914:                                        log
0915:                                                .debug("portlet descriptors for application "
0916:                                                        + contextName
0917:                                                        + " have changed.");
0918:                                    }
0919:                                    checksum = newChecksum;
0920:                                    // reset this to restart unsuccessful PA start handling for evers PA descriptor change
0921:                                    unsuccessfulStarts = 0;
0922:                                    return true;
0923:                                }
0924:                            }
0925:                        }
0926:                        return false;
0927:                    }
0928:
0929:                    public void setObsolete() {
0930:                        obsolete = true;
0931:                    }
0932:
0933:                    public boolean isObsolete() {
0934:                        return obsolete;
0935:                    }
0936:
0937:                    public int getUnsuccessfulStarts() {
0938:                        return unsuccessfulStarts;
0939:                    }
0940:
0941:                    public void setUnsuccessfulStarts(int unsuccessfulStarts) {
0942:                        this .unsuccessfulStarts = unsuccessfulStarts;
0943:                    }
0944:
0945:                    public String getContextPath() {
0946:                        return contextPath;
0947:                    }
0948:                }
0949:
0950:                private PortletApplicationManager pam;
0951:                private long interval;
0952:                private boolean started = true;
0953:                private ArrayList monitorInfos;
0954:                private int maxRetriedStarts;
0955:
0956:                public DescriptorChangeMonitor(ThreadGroup group, String name,
0957:                        PortletApplicationManager pam, long interval,
0958:                        int maxretriedStarts) {
0959:                    super (group, name);
0960:                    this .pam = pam;
0961:                    this .interval = interval;
0962:                    monitorInfos = new ArrayList();
0963:                    setPriority(MIN_PRIORITY);
0964:                    setDaemon(true);
0965:                    this .maxRetriedStarts = maxretriedStarts;
0966:                }
0967:
0968:                public void run() {
0969:                    try {
0970:                        sleep(interval);
0971:                    } catch (InterruptedException e) {
0972:                    }
0973:                    while (started) {
0974:                        checkDescriptorChanges();
0975:
0976:                        try {
0977:                            sleep(interval);
0978:                        } catch (InterruptedException e) {
0979:
0980:                        }
0981:                    }
0982:                }
0983:
0984:                /**
0985:                 * notifies a switch variable that exits the watcher's montior loop started in the <code>run()</code> method.
0986:                 */
0987:                public synchronized void safeStop() {
0988:                    started = false;
0989:                    monitorInfos.clear();
0990:                }
0991:
0992:                public synchronized void monitor(String contextName,
0993:                        String contextPath, ClassLoader paClassLoader,
0994:                        int paType, File paDir, long checksum) {
0995:                    monitorInfos.add(new DescriptorChangeMonitorInfo(
0996:                            contextName, contextPath, paClassLoader, paType,
0997:                            paDir, checksum));
0998:                }
0999:
1000:                public synchronized void remove(String contextName) {
1001:                    DescriptorChangeMonitorInfo monitorInfo;
1002:                    for (int i = monitorInfos.size() - 1; i > -1; i--) {
1003:                        monitorInfo = (DescriptorChangeMonitorInfo) monitorInfos
1004:                                .get(i);
1005:                        if (contextName.equals(monitorInfo.getContextName())) {
1006:                            // will be removed by checkDescriptorChanges on next iteration
1007:                            monitorInfo.setObsolete();
1008:                            break;
1009:                        }
1010:                    }
1011:                }
1012:
1013:                public synchronized DescriptorChangeMonitorInfo get(
1014:                        String contextName) {
1015:                    DescriptorChangeMonitorInfo monitorInfo;
1016:                    for (int i = monitorInfos.size() - 1; i > -1; i--) {
1017:                        monitorInfo = (DescriptorChangeMonitorInfo) monitorInfos
1018:                                .get(i);
1019:                        if (contextName.equals(monitorInfo.getContextName())) {
1020:                            return monitorInfo;
1021:                        }
1022:                    }
1023:                    return null;
1024:                }
1025:
1026:                public boolean isMonitored(String contextName) {
1027:                    DescriptorChangeMonitorInfo monitorInfo = this 
1028:                            .get(contextName);
1029:                    if (monitorInfo != null && !monitorInfo.isObsolete()) {
1030:                        return true;
1031:                    }
1032:                    return false;
1033:                }
1034:
1035:                private void checkDescriptorChanges() {
1036:                    int size;
1037:                    synchronized (this ) {
1038:                        size = monitorInfos.size();
1039:                    }
1040:
1041:                    if (log.isDebugEnabled()) {
1042:                        log
1043:                                .debug("check for portlet application descriptor changes.");
1044:                    }
1045:
1046:                    for (int i = size - 1; i > -1; i--) {
1047:                        DescriptorChangeMonitorInfo monitorInfo;
1048:                        synchronized (this ) {
1049:                            if (started) {
1050:                                monitorInfo = (DescriptorChangeMonitorInfo) monitorInfos
1051:                                        .get(i);
1052:                                if (monitorInfo.isObsolete()) {
1053:                                    monitorInfos.remove(i);
1054:                                } else {
1055:                                    try {
1056:                                        int unsuccessfulStarts = monitorInfo
1057:                                                .getUnsuccessfulStarts();
1058:                                        // try to restart PA if the PA-descriptors have change
1059:                                        // OR (if we encountered an exception while starting the PA)
1060:                                        // keep on trying to restart PA until maxRetriedStarts is reached
1061:                                        // This ensures we finally startup in a clustered enviroment, where parallel registration
1062:                                        // of PAs could lead to contraint violation eceptions in DB.
1063:                                        // see https://issues.apache.org/jira/browse/JS2-666
1064:                                        // Note: monitorInfo.isChanged() will reset unsuccessfulStarts to 0 if a PA descriptor change 
1065:                                        // has been detected (monitorInfo.isChanged() == true).
1066:                                        if (monitorInfo.isChanged()
1067:                                                || (unsuccessfulStarts > 0 && unsuccessfulStarts <= maxRetriedStarts)) {
1068:                                            try {
1069:                                                pam
1070:                                                        .startPA(
1071:                                                                monitorInfo
1072:                                                                        .getContextName(),
1073:                                                                monitorInfo
1074:                                                                        .getContextPath(),
1075:                                                                new DirectoryHelper(
1076:                                                                        monitorInfo
1077:                                                                                .getPADir()),
1078:                                                                monitorInfo
1079:                                                                        .getPAClassLoader(),
1080:                                                                monitorInfo
1081:                                                                        .getPortletApplicationType(),
1082:                                                                monitorInfo
1083:                                                                        .getChecksum());
1084:                                                // great! we have a successful start. set unsuccessful starts to 0
1085:                                                monitorInfo
1086:                                                        .setUnsuccessfulStarts(0);
1087:                                            } catch (Exception e) {
1088:                                                if (monitorInfo.isChanged()) {
1089:                                                    log
1090:                                                            .error(
1091:                                                                    "Failed to restart PortletApplication "
1092:                                                                            + monitorInfo
1093:                                                                                    .getContextName(),
1094:                                                                    e);
1095:                                                } else if (log.isWarnEnabled()) {
1096:                                                    log
1097:                                                            .warn(
1098:                                                                    "Failed to restart PortletApplication "
1099:                                                                            + monitorInfo
1100:                                                                                    .getContextName(),
1101:                                                                    e);
1102:                                                }
1103:                                                // we encountered an error while starting the PA
1104:                                                // this could result from clustered environments problems (see above)
1105:                                                // increase unsuccessfulStarts until the maxRetriedStarts is reached
1106:                                                monitorInfo
1107:                                                        .setUnsuccessfulStarts(unsuccessfulStarts + 1);
1108:                                                if (log.isDebugEnabled()) {
1109:                                                    log
1110:                                                            .debug("Number of unsuccessful PA starts is "
1111:                                                                    + monitorInfo
1112:                                                                            .getUnsuccessfulStarts()
1113:                                                                    + ".");
1114:                                                }
1115:                                                if (monitorInfo
1116:                                                        .getUnsuccessfulStarts() > maxRetriedStarts) {
1117:                                                    log
1118:                                                            .error("Max number of retries ("
1119:                                                                    + maxRetriedStarts
1120:                                                                    + ") reached. Ignoring Monitor for "
1121:                                                                    + monitorInfo
1122:                                                                            .getContextName());
1123:                                                }
1124:                                            }
1125:                                        }
1126:                                    } catch (Exception e) {
1127:                                        // ignore filesystem and/or descriptor errors, maybe next time round they'll be fixed again
1128:                                        log
1129:                                                .error(
1130:                                                        "Descriptor Change check failure for PortletApplication "
1131:                                                                + monitorInfo
1132:                                                                        .getContextName(),
1133:                                                        e);
1134:                                    }
1135:                                }
1136:                            }
1137:                        }
1138:                    }
1139:                }
1140:            }
1141:
1142:            public void setMaxRetriedStarts(int maxRetriedStarts) {
1143:                this .maxRetriedStarts = maxRetriedStarts;
1144:            }
1145:
1146:            public int getMaxRetriedStarts() {
1147:                return maxRetriedStarts;
1148:            }
1149:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.