portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dlest...@apache.org
Subject svn commit: r209328 [4/14] - in /portals/jetspeed-2/trunk/components/portal: src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jetspeed/ src/java/org/apache/jetspeed/aggregator/ src/java/org/apache/jetspeed/aggregator/impl/ src/java...
Date Tue, 05 Jul 2005 21:55:50 GMT
Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/PortletWindowSessionNavigationalStates.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.state.impl;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+
+import org.apache.jetspeed.Jetspeed;
+import org.apache.jetspeed.container.window.PortletWindowAccessor;
+import org.apache.jetspeed.om.page.Page;
+import org.apache.pluto.om.window.PortletWindow;
+
+public class PortletWindowSessionNavigationalStates implements Serializable
+{
+    private static final class PageState implements Serializable
+    {
+        public Map windowStates = new HashMap();
+        public String maximizedWindowId;
+    }
+    
+    private final boolean storeParameters;
+    
+    private Map pageStates = new HashMap();
+
+    public PortletWindowSessionNavigationalStates(boolean storeParameters)
+    {
+        this.storeParameters = storeParameters;
+    }
+    
+    public void sync(Page page, PortletWindowRequestNavigationalStates requestStates)
+    {
+        PageState pageState = (PageState)pageStates.get(page.getId());
+        if ( pageState == null )
+        {
+            pageState = new PageState();
+            pageStates.put(page.getId(), pageState);
+        }
+        
+        PortletWindowRequestNavigationalState requestState = null;
+        PortletWindowBaseNavigationalState sessionState = null;
+
+        // first synchronize MAXIMIZED window
+        if ( pageState.maximizedWindowId != null )
+        {
+            String requestMaximizedWindowId = null;
+            
+            if ( requestStates.getMaximizedWindow() != null )
+            {
+                requestMaximizedWindowId = requestStates.getMaximizedWindow().getId().toString();
+            }
+                
+            if ( requestMaximizedWindowId == null )
+            {
+                // check clearing MAXIMIZED window
+                requestState = requestStates.getPortletWindowNavigationalState(pageState.maximizedWindowId);
+                if ( requestState != null )
+                {
+                    if (requestState.getWindowState() != null)
+                    {
+                        pageState.maximizedWindowId = null;
+                        // syncState will reset the sessionState.WindowState
+                    }                         
+                }
+                else
+                {
+                    // check PortletWindow still exists...
+                    // depends on PortletWindowAccessor cache to be active
+                    PortletWindowAccessor accessor = 
+                        (PortletWindowAccessor)Jetspeed.getComponentManager().getComponent(PortletWindowAccessor.class);
+                    PortletWindow maximizedWindow = accessor.getPortletWindow(pageState.maximizedWindowId);
+                    if ( maximizedWindow == null )
+                    {
+                        // gone: remove sessionState
+                        pageState.windowStates.remove(pageState.maximizedWindowId);
+                        pageState.maximizedWindowId = null;
+                    }
+                    else
+                    {
+                        requestStates.setMaximizedWindow(maximizedWindow);
+                    }
+                }
+            }
+            else if ( !requestMaximizedWindowId.equals( pageState.maximizedWindowId ))
+            {
+                // When can a non-maximized window request maximized state while another already has it?
+                // Maybe from a decoration portlet which always needs to be viewable?
+                requestState = requestStates.getPortletWindowNavigationalState(pageState.maximizedWindowId);
+                sessionState = (PortletWindowBaseNavigationalState)pageState.windowStates.get(pageState.maximizedWindowId);
+                if ( requestState == null || requestState.getWindowState() == null )
+                {
+                    // need to clear it ourselves first
+                    sessionState.setWindowState(null);
+                }
+            }
+        }
+        
+        if ( requestStates.getMaximizedWindow() != null )
+        {
+            // store the new MAXIMIZED window
+            pageState.maximizedWindowId = requestStates.getMaximizedWindow().getId().toString();
+        }
+        
+        Iterator iter = requestStates.getWindowIdIterator();
+        String actionWindowId = requestStates.getActionWindow() != null ? requestStates.getActionWindow().getId().toString() : null;
+        boolean actionRequestState = false;
+        
+        // now synchronize requestStates and sessionStates
+        while ( iter.hasNext() )
+        {
+            requestState = requestStates.getPortletWindowNavigationalState((String)iter.next());
+            sessionState = (PortletWindowBaseNavigationalState)pageState.windowStates.get(requestState.getWindowId());
+            if ( sessionState == null )
+            {
+                if ( storeParameters )
+                {
+                    sessionState = new PortletWindowExtendedNavigationalState();
+                }
+                else
+                {
+                    sessionState = new PortletWindowBaseNavigationalState();
+                }
+                pageState.windowStates.put(requestState.getWindowId(),sessionState);
+            }
+
+            actionRequestState = actionWindowId != null && actionWindowId.equals(requestState.getWindowId());
+            syncStates(actionRequestState, requestState, sessionState);            
+        }
+        
+        // now copy missing requestStates from the pageState
+        iter = pageState.windowStates.keySet().iterator();
+        String windowId;
+        while ( iter.hasNext() )
+        {
+            windowId = (String)iter.next();
+            requestState = requestStates.getPortletWindowNavigationalState(windowId);
+            PortletWindow portletWindow = null;
+            if ( requestState == null )
+            {
+                requestState = new PortletWindowRequestNavigationalState(windowId);
+                syncStates(false, requestState,(PortletWindowBaseNavigationalState)pageState.windowStates.get(windowId));
+                requestStates.addPortletWindowNavigationalState(windowId, requestState);
+            }
+        }        
+    }
+    
+    private void syncStates(boolean actionRequestState, PortletWindowRequestNavigationalState requestState, PortletWindowBaseNavigationalState sessionState)
+    {
+        if ( requestState.getPortletMode() != null )
+        {
+            if ( requestState.getPortletMode().equals(PortletMode.VIEW) )
+            {
+                sessionState.setPortletMode(null);
+            }
+            else
+            {
+                sessionState.setPortletMode(requestState.getPortletMode());
+            }
+        }
+        else if ( sessionState.getPortletMode() == null )
+        {
+            requestState.setPortletMode(PortletMode.VIEW);
+        }
+        else
+        {
+            requestState.setPortletMode(sessionState.getPortletMode());
+        }
+        
+        if ( requestState.getWindowState() != null )
+        {
+            if ( requestState.getWindowState().equals(WindowState.NORMAL) )
+            {
+                sessionState.setWindowState(null);
+            }
+            else
+            {
+                sessionState.setWindowState(requestState.getWindowState());
+            }
+        }
+        else if ( sessionState.getWindowState() == null )
+        {
+            requestState.setWindowState(WindowState.NORMAL);
+        }
+        else        
+        {
+            requestState.setWindowState(sessionState.getWindowState());
+        }
+        
+        if (storeParameters)
+        {
+            PortletWindowExtendedNavigationalState extendedSessionState = (PortletWindowExtendedNavigationalState)sessionState;
+            if ( requestState.getParametersMap() != null )
+            {
+                if ( actionRequestState )
+                {
+                    // never store ActionRequest parameters in session
+                    extendedSessionState.setParametersMap(null);
+                }
+                else 
+                {
+                    extendedSessionState.setParametersMap(new HashMap(requestState.getParametersMap()));
+                }
+            }
+            else if ( requestState.isClearParameters() )
+            {
+                extendedSessionState.setParametersMap(null);
+                requestState.setClearParameters(false);
+            }            
+            else if ( extendedSessionState.getParametersMap() != null )
+            {
+                requestState.setParametersMap(new HashMap(extendedSessionState.getParametersMap()));
+            }
+        }
+    }    
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionFullNavigationalState.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionFullNavigationalState.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionFullNavigationalState.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionFullNavigationalState.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.state.impl;
+
+
+/**
+ * SessionFullNavigationalState, stores all nav parameters in the session, including render parameters
+ *
+ * @author <a href="mailto:ate@apache.org">Ate Douma</a>
+ * @version $Id: SessionFullNavigationalState.java 187753 2004-10-15 21:47:25Z ate $
+ */
+public class SessionFullNavigationalState extends SessionNavigationalState
+{    
+    public SessionFullNavigationalState(NavigationalStateCodec codec)
+    {
+        super(codec);
+    }
+
+    public boolean isRenderParameterStateFull()
+    {
+        return true;
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionNavigationalState.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionNavigationalState.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionNavigationalState.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/state/impl/SessionNavigationalState.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.state.impl;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.jetspeed.container.state.NavigationalState;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * SessionNavigationalState, stores nav parameters in the session, not on URL
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: SessionNavigationalState.java 187753 2004-10-15 21:47:25Z ate $
+ */
+public class SessionNavigationalState extends AbstractNavigationalState
+{    
+    public SessionNavigationalState(NavigationalStateCodec codec)
+    {
+        super(codec);
+    }
+
+    public synchronized void sync(RequestContext context)
+    {
+        HttpSession session = context.getRequest().getSession();
+        if ( session != null )
+        {
+            PortletWindowSessionNavigationalStates sessionStates = (PortletWindowSessionNavigationalStates)session.getAttribute(NavigationalState.NAVSTATE_SESSION_KEY);
+            if ( sessionStates == null )
+            {
+                sessionStates = new PortletWindowSessionNavigationalStates(isRenderParameterStateFull());
+                session.setAttribute(NavigationalState.NAVSTATE_SESSION_KEY, sessionStates);
+            }
+            sessionStates.sync(context.getPage(),getPortletWindowRequestNavigationalStates());
+        }
+    }
+    
+    public boolean isNavigationalParameterStateFull()
+    {
+        return true;
+    }
+
+    public boolean isRenderParameterStateFull()
+    {
+        return false;
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/AbstractPortalURL.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/AbstractPortalURL.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/AbstractPortalURL.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/AbstractPortalURL.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.url.impl;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.jetspeed.Jetspeed;
+import org.apache.jetspeed.container.ContainerConstants;
+import org.apache.jetspeed.container.state.NavigationalState;
+import org.apache.jetspeed.container.url.PortalURL;
+import org.apache.pluto.om.window.PortletWindow;
+
+/**
+ * AbstractPortalURL delivers the base implemention for parsing Jetspeed Portal URLs and creating new Portlet URLs.
+ * Not implemented is the encoding and decoding of the NavigationState parameter in the URL, allowing concrete
+ * implementations to supply different algorithms for it like encoding it as pathInfo or as query string parameter.
+ *
+ * @author <a href="mailto:ate@apache.org">Ate Douma</a>
+ * @version $Id: AbstractPortalURL.java 188504 2005-04-21 07:52:15Z ate $
+ */
+public abstract class AbstractPortalURL implements PortalURL
+{
+    public static final String DEFAULT_NAV_STATE_PARAMETER = "_ns";
+    
+    private static String navStateParameter;
+    
+    private NavigationalState navState;
+    private String serverName;    
+    private String serverScheme;
+    private String contextPath;
+    private String basePath;
+    private String path;
+    private String encodedNavState;
+    private String secureBaseURL;
+    private String nonSecureBaseURL;
+    private int serverPort;    
+    private boolean secure;
+    private String characterEncoding;
+    
+    public AbstractPortalURL(HttpServletRequest request, String characterEncoding, NavigationalState navState)
+    {
+        if ( navStateParameter == null )
+        {
+            navStateParameter = 
+                Jetspeed.getContext().getConfigurationProperty("portalurl.navigationalstate.parameter.name", 
+                        DEFAULT_NAV_STATE_PARAMETER);
+        }
+        
+        this.navState = navState;
+        this.characterEncoding = characterEncoding;
+
+        if (null != request)
+        {
+            decodeBaseURL(request);
+            
+            decodeBasePath(request);
+            
+            decodePathAndNavigationalState(request);
+        }
+    }
+    
+    public static String getNavigationalStateParameterName()
+    {
+        return navStateParameter;
+    }
+    
+    protected void decodeBaseURL(HttpServletRequest request)
+    {
+        this.serverName = request.getServerName();
+        this.serverPort = request.getServerPort();
+        this.serverScheme = request.getScheme();
+        this.secure = request.isSecure();
+        StringBuffer buffer = new StringBuffer(this.serverScheme);
+        buffer.append("://");
+        buffer.append(this.serverName);
+        if ((this.serverScheme.equals(HTTP) && this.serverPort != 80) ||
+                (this.serverScheme.equals(HTTPS) && this.serverPort != 443))
+        {
+            buffer.append(":");
+            buffer.append(this.serverPort);
+        }
+        if ( secure )
+        {
+            this.secureBaseURL = buffer.toString();
+        }
+        else
+        {
+            this.nonSecureBaseURL = buffer.toString();
+        }
+    }
+    
+    protected void decodeBasePath(HttpServletRequest request)
+    {
+        this.contextPath = (String) request.getAttribute(ContainerConstants.PORTAL_CONTEXT);
+        if (contextPath == null)
+        {
+            contextPath = request.getContextPath();
+        }
+        if (contextPath == null)
+        {
+            contextPath = "";
+        }
+        String servletPath = request.getServletPath();
+        if (servletPath == null)
+        {
+            servletPath = "";
+        }
+        this.basePath = contextPath + servletPath;
+    }
+
+    protected void setEncodedNavigationalState(String encodedNavigationalState)
+    {
+        this.encodedNavState = encodedNavigationalState;        
+        try
+        {
+            navState.init(encodedNavState, characterEncoding);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            // should never happen
+            e.printStackTrace();
+        }
+    }
+
+    protected void setPath(String path)
+    {
+        this.path = path;
+    }
+
+    public String getBaseURL()
+    {
+        return getBaseURL(secure);
+    }
+    
+    public String getBaseURL(boolean secure)
+    {
+        // TODO: delivering both secure and non-secure baseURL for PLT.7.1.2
+        //       currently only the baseURL as decoded (secure or non-secure) is returned
+        //       and the secure parameter is ignored
+        return this.secure ? secureBaseURL : nonSecureBaseURL;
+    }
+    
+    public String getBasePath()
+    {
+        return basePath;
+    }
+    
+    public String getPath()
+    {
+        return path;
+    }    
+
+    public String getPageBasePath()
+    {
+        if ( null == path || (1 == path.length() && '/' == path.charAt(0)) )
+        {
+            return basePath;
+        }
+        else if ( -1 != path.indexOf('/') && !path.endsWith("/") )
+        {
+            return basePath + path.substring(0, path.lastIndexOf('/') );
+        }
+        else
+        {
+            return basePath + path;
+        }
+    }
+    
+    public boolean isSecure()
+    {
+        return secure;
+    }
+        
+    public NavigationalState getNavigationalState()
+    {
+        return navState;
+    }
+
+    public String createPortletURL(PortletWindow window, Map parameters, PortletMode mode, WindowState state, boolean action, boolean secure)
+    {
+        try
+        {
+            return createPortletURL(navState.encode(window,parameters,mode,state,action), secure);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            // should never happen
+            e.printStackTrace();
+            // to keep the compiler happy
+            return null;
+        }
+    }
+
+    public String createPortletURL(PortletWindow window, PortletMode mode, WindowState state, boolean secure)
+    {
+        try
+        {
+            return createPortletURL(navState.encode(window,mode,state), secure);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            // should never happen
+            e.printStackTrace();
+            // to keep the compiler happy
+            return null;
+        }
+    }    
+
+    protected abstract void decodePathAndNavigationalState(HttpServletRequest request);
+    
+    protected abstract String createPortletURL(String encodedNavState, boolean secure);
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/JetspeedPortletURL.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/JetspeedPortletURL.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/JetspeedPortletURL.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/JetspeedPortletURL.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2003,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.url.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.pluto.core.impl.PortletURLImpl;
+import org.apache.pluto.om.window.PortletWindow;
+
+/**
+ * Jetspeed extension of the Pluto PortalURLImpl providing support for session url rewriting
+ * when cookies are disabled.
+ *
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id: JetspeedPortletURL.java 188598 2005-05-24 02:10:58Z ate $
+ */
+public class JetspeedPortletURL extends PortletURLImpl
+{
+    public JetspeedPortletURL(PortletWindow portletWindow, HttpServletRequest servletRequest, HttpServletResponse servletResponse, boolean isAction)
+    {
+        super(portletWindow, servletRequest, servletResponse, isAction);
+    }
+
+    public String toString()
+    {
+        return servletResponse.encodeURL(super.toString());
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PathInfoEncodingPortalURL.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PathInfoEncodingPortalURL.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PathInfoEncodingPortalURL.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PathInfoEncodingPortalURL.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.url.impl;
+
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.jetspeed.container.state.NavigationalState;
+
+/**
+ * PathInfoEncodingPortalURL encodes the NavigationalState as PathInfo element
+ * *
+ * @author <a href="mailto:ate@apache.org">Ate Douma</a>
+ * @version $Id: PathInfoEncodingPortalURL.java 187758 2004-10-17 14:02:38Z ate $
+ */
+public class PathInfoEncodingPortalURL extends AbstractPortalURL
+{
+    public PathInfoEncodingPortalURL(HttpServletRequest request, String characterEncoding, NavigationalState navState)
+    {
+        super(request, characterEncoding, navState);
+    }
+    
+    protected void decodePathAndNavigationalState(HttpServletRequest request)
+    {
+        String path = null;
+        String encodedNavState = null;
+
+        String pathInfo = request.getPathInfo();
+        if (pathInfo != null)
+        {
+            StringTokenizer tokenizer = new StringTokenizer(request.getPathInfo(),"/");
+            StringBuffer buffer = new StringBuffer();
+            String token;
+            boolean foundNavState = false;
+            String navStatePrefix = getNavigationalStateParameterName() +":";
+            while (tokenizer.hasMoreTokens())
+            {
+                token = tokenizer.nextToken();
+                if (!foundNavState && token.startsWith(navStatePrefix))
+                {
+                    foundNavState = true;
+                    if ( token.length() > navStatePrefix.length() )
+                    {
+                        encodedNavState = token.substring(navStatePrefix.length());
+                    }
+                }
+                else
+                {
+                    buffer.append("/");
+                    buffer.append(token);
+                }
+            }
+            if ( buffer.length() > 0 )
+            {
+                path = buffer.toString();
+            }
+            else
+            {
+                path = "/";
+            }
+        }
+        setPath(path);
+        setEncodedNavigationalState(encodedNavState);
+    }
+
+    protected String createPortletURL(String encodedNavState, boolean secure)
+    {
+        StringBuffer buffer = new StringBuffer(getBaseURL(secure));
+        buffer.append(getBasePath());
+        if ( encodedNavState != null )
+        {
+            buffer.append("/");
+            buffer.append(getNavigationalStateParameterName());
+            buffer.append(":");
+            buffer.append(encodedNavState);
+        }
+        if ( getPath() != null )
+        {
+            buffer.append(getPath());
+        }
+        return buffer.toString();
+    }        
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortalURLValveImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortalURLValveImpl.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortalURLValveImpl.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortalURLValveImpl.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jetspeed.container.url.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.Jetspeed;
+import org.apache.jetspeed.container.state.NavigationalStateComponent;
+import org.apache.jetspeed.pipeline.PipelineException;
+import org.apache.jetspeed.pipeline.valve.AbstractValve;
+import org.apache.jetspeed.pipeline.valve.ValveContext;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * Creates the PortalURL for the current Request
+ *
+ * @author <a href="mailto:ate@apache.org">Ate Douma</a>
+ * @version $Id: PortalURLValveImpl.java 187758 2004-10-17 14:02:38Z ate $
+ */
+public class PortalURLValveImpl extends AbstractValve
+{
+    private static final Log log = LogFactory.getLog(PortalURLValveImpl.class);
+    
+    public void invoke(RequestContext request, ValveContext context)
+        throws PipelineException
+    {
+        try
+        {  
+            if ( request.getPortalURL() == null )
+            {
+                NavigationalStateComponent navComponent = (NavigationalStateComponent)Jetspeed.getComponentManager()
+                    .getComponent(NavigationalStateComponent.class);
+                request.setPortalURL(navComponent.createURL(request.getRequest(), request.getCharacterEncoding()));
+            }
+        }
+        catch (Exception e)
+        {
+            throw new PipelineException(e);
+        }
+        // Pass control to the next Valve in the Pipeline
+        context.invokeNext( request );
+    }
+
+    public String toString()
+    {
+        return "PortalURLValveImpl";
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortletURLFactoryImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortletURLFactoryImpl.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortletURLFactoryImpl.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/PortletURLFactoryImpl.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.url.impl;
+
+import javax.portlet.PortletURL;
+
+import org.apache.pluto.factory.PortletURLFactory;
+import org.apache.pluto.om.window.PortletWindow;
+
+/**
+ * Jetspeed implementation of the Pluto PortalURLFactory
+ *
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id: PortletURLFactoryImpl.java 188598 2005-05-24 02:10:58Z ate $
+ */
+public class PortletURLFactoryImpl implements PortletURLFactory {
+
+    public void init(javax.servlet.ServletConfig config, java.util.Map properties) throws Exception
+    {
+    }
+
+    public PortletURL getPortletURL(PortletWindow portletWindow,
+                                    javax.servlet.http.HttpServletRequest servletRequest,
+                                    javax.servlet.http.HttpServletResponse servletResponse)
+    {
+        return getPortletURL(portletWindow, servletRequest, servletResponse, false);
+    }
+
+    public PortletURL getPortletURL(PortletWindow portletWindow,
+                                    javax.servlet.http.HttpServletRequest servletRequest,
+                                    javax.servlet.http.HttpServletResponse servletResponse,
+                                    boolean isAction)
+    {
+        return new JetspeedPortletURL(portletWindow, servletRequest, servletResponse, isAction);
+    }
+
+    public void destroy() throws Exception
+    {
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/QueryStringEncodingPortalURL.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/QueryStringEncodingPortalURL.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/QueryStringEncodingPortalURL.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/url/impl/QueryStringEncodingPortalURL.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.url.impl;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.jetspeed.container.state.NavigationalState;
+
+/**
+ * QueryStringEncodingPortalURL encodes the NavigationalState as query parameter
+ * *
+ * @author <a href="mailto:ate@apache.org">Ate Douma</a>
+ * @version $Id: QueryStringEncodingPortalURL.java 187758 2004-10-17 14:02:38Z ate $
+ */
+public class QueryStringEncodingPortalURL extends AbstractPortalURL
+{
+    public QueryStringEncodingPortalURL(HttpServletRequest request, String characterEncoding, NavigationalState navState)
+    {
+        super(request, characterEncoding, navState);
+    }
+
+    protected void decodePathAndNavigationalState(HttpServletRequest request)
+    {
+        setEncodedNavigationalState(request.getParameter(getNavigationalStateParameterName()));
+        String path = null;
+        if (request.getPathInfo() != null)
+        {
+            path = request.getPathInfo();
+            int length = path.length();
+            if ( length > 1 && path.endsWith("/") )
+            {
+                path = path.substring(0, length-1);
+            }
+        }
+        setPath(path);
+    }
+    
+    protected String createPortletURL(String encodedNavigationalState, boolean secure)
+    {
+        StringBuffer buffer = new StringBuffer(getBaseURL(secure));
+        buffer.append(getBasePath());
+        if ( getPath() != null )
+        {
+            buffer.append(getPath());
+        }
+        if ( encodedNavigationalState != null )
+        {
+            buffer.append("?");
+            buffer.append(getNavigationalStateParameterName());
+            buffer.append("=");
+            buffer.append(encodedNavigationalState);
+        }
+        return buffer.toString();
+    }    
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/window/impl/PortletWindowAccessorImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/window/impl/PortletWindowAccessorImpl.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/window/impl/PortletWindowAccessorImpl.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/container/window/impl/PortletWindowAccessorImpl.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.container.window.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
+import org.apache.jetspeed.components.portletentity.PortletEntityNotGeneratedException;
+import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
+import org.apache.jetspeed.container.window.FailedToCreateWindowException;
+import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
+import org.apache.jetspeed.container.window.PortletWindowAccessor;
+import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
+import org.apache.jetspeed.om.page.ContentFragment;
+import org.apache.jetspeed.om.window.impl.PortletWindowImpl;
+import org.apache.jetspeed.util.ArgUtil;
+import org.apache.pluto.om.entity.PortletEntity;
+import org.apache.pluto.om.window.PortletWindow;
+import org.apache.pluto.om.window.PortletWindowCtrl;
+
+/**
+ * Portlet Window Accessor Implementation
+ *
+ * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
+ * @version $Id: PortletWindowAccessorImpl.java,v 1.12 2005/04/29 14:01:57 weaver Exp $
+ */
+public class PortletWindowAccessorImpl implements PortletWindowAccessor 
+{
+    protected final static Log log = LogFactory.getLog(PortletWindowAccessorImpl.class);
+   
+    private Map windows = new HashMap();
+    private PortletEntityAccessComponent entityAccessor;
+    private boolean validateWindows = false;
+    
+
+    public PortletWindowAccessorImpl(PortletEntityAccessComponent entityAccessor, boolean validateWindows)
+    {
+        this.entityAccessor = entityAccessor;
+        this.validateWindows = validateWindows;
+    }
+
+    public PortletWindow createPortletWindow(PortletEntity entity, String windowId)
+    {
+        if(entity == null)
+        {
+            throw new IllegalArgumentException("cratePortletWindow requires a non-null PortletEntity");
+        }
+        
+        PortletWindow found = getWindowFromCache(windowId);
+        if (found != null)
+        {
+            ((PortletWindowCtrl)found).setPortletEntity(entity);
+            return found;
+        }
+        
+        PortletWindowImpl window = new PortletWindowImpl(windowId);
+        window.setPortletEntity(entity);
+        windows.put(windowId, window);
+        return window;        
+    }
+
+    public PortletWindow createPortletWindow(String windowId)
+    {
+        PortletWindow found = getWindowFromCache(windowId);
+        if (found != null)
+        {
+            return found;
+        }        
+        PortletWindowImpl window = new PortletWindowImpl(windowId);
+        return window;                
+    }
+    
+    public PortletWindow getPortletWindow(String windowId)
+    {
+        return getWindowFromCache(windowId);
+    }
+    
+    public PortletWindow getPortletWindow(ContentFragment fragment) throws FailedToRetrievePortletWindow, PortletEntityNotStoredException
+    {
+        ArgUtil.assertNotNull(ContentFragment.class, fragment, this, "getPortletWindow(Fragment fragment)");
+        PortletWindow portletWindow = getWindowFromCache(fragment);
+        if (portletWindow == null)
+        {
+            try
+            {
+                return createPortletWindow(fragment);
+            }
+            catch (FailedToCreateWindowException e)
+            {
+                throw new FailedToRetrievePortletWindow(e.toString(), e);
+            }
+        }
+        else
+        {
+            if (validateWindows)
+            {
+                validateWindow(fragment, portletWindow);
+            }
+        }
+        
+        return portletWindow;
+    }
+    
+    /**
+     * <p>
+     * validateWindow
+     * </p>
+     *
+     * @param fragment
+     * @param portletWindow
+     * @throws PortletEntityNotStoredException 
+     * @throws InconsistentWindowStateException
+     */
+    protected void validateWindow( ContentFragment fragment, PortletWindow portletWindow ) throws FailedToRetrievePortletWindow, PortletEntityNotStoredException
+    {
+        // make sure the window has the most up-to-date portlet entity
+        PortletEntity portletEntity = entityAccessor.getPortletEntityForFragment(fragment);
+        if(portletEntity != null)
+        {
+            ((PortletWindowCtrl) portletWindow).setPortletEntity(portletEntity);
+        }
+        else
+        {
+            removeWindow(portletWindow);  
+            throw new FailedToRetrievePortletWindow("No PortletEntity exists for for id "+fragment.getId()+" removing window from cache.");
+        }
+    }
+
+    public PortletWindow getPortletWindow(ContentFragment fragment, String principal) throws FailedToRetrievePortletWindow, FailedToCreateWindowException, PortletEntityNotStoredException
+    {
+        ArgUtil.assertNotNull(ContentFragment.class, fragment, this, "getPortletWindow(Fragment fragment, String principal)");
+        ArgUtil.assertNotNull(String.class, principal, this, "getPortletWindow(Fragment fragment, String principal)");
+        PortletWindow portletWindow = getWindowFromCache(fragment);
+        if (portletWindow == null)
+        {
+            return createPortletWindow(fragment, principal);
+        }        
+        else
+        {
+            // make sure the window has the most up-to-date portlet entity
+            validateWindow(fragment, portletWindow);
+        }
+        return portletWindow;
+    }
+
+    private PortletWindow createPortletWindow(ContentFragment fragment) throws FailedToCreateWindowException, PortletEntityNotStoredException
+    {
+        return createPortletWindow(fragment, null);
+    }
+    
+    private PortletWindow createPortletWindow(ContentFragment fragment, String principal) throws FailedToCreateWindowException, PortletEntityNotStoredException
+    {
+        PortletWindow portletWindow = new PortletWindowImpl(fragment.getId());
+                
+        MutablePortletEntity portletEntity = entityAccessor.getPortletEntityForFragment(fragment, principal);
+        if (portletEntity == null)
+        {
+            log.info("No portlet entity defined for fragment ID "+fragment.getId()+" attempting to auto-generate...");
+            try
+            {
+                portletEntity = entityAccessor.generateEntityFromFragment(fragment, principal);
+                // not portlet definition most likely means that the portlet has not been deployed so dont worry about storing off the entity
+                if(portletEntity.getPortletDefinition() != null)
+                {
+                    entityAccessor.storePortletEntity(portletEntity);
+                }
+            }
+            catch (PortletEntityNotGeneratedException e)
+            {
+                throw new FailedToCreateWindowException("Error generating new PortletEntity: "+e.toString(), e);                
+            }
+            catch (PortletEntityNotStoredException e)
+            {
+                throw new FailedToCreateWindowException("Error storing new PortletEntity: "+e.toString(), e);
+            }
+            
+            if(portletEntity == null)
+            {
+                throw new FailedToCreateWindowException("Unable to generate portlet entity.");
+            }
+            
+        }
+        ((PortletWindowCtrl) portletWindow).setPortletEntity(portletEntity);
+        
+        windows.put(fragment.getId(), portletWindow);       
+        
+        
+        return portletWindow;
+    }
+    
+    public void removeWindows(PortletEntity portletEntity)
+    {
+        Iterator entityWindows = portletEntity.getPortletWindowList().iterator();
+        while(entityWindows.hasNext())
+        {
+            Object obj = entityWindows.next();
+            PortletWindow window = (PortletWindow) obj;
+            removeWindow(window);
+        }
+    }
+    
+    public void removeWindow(PortletWindow window)
+    {
+        windows.remove(window.getId().toString());
+    }
+    
+    private PortletWindow getWindowFromCache(ContentFragment fragment)
+    {
+        return (PortletWindow)windows.get(fragment.getId());
+    }
+    
+    private PortletWindow getWindowFromCache(String id)
+    {
+        return (PortletWindow)windows.get(id);
+    }
+    
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployDecoratorEventListener.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployDecoratorEventListener.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployDecoratorEventListener.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployDecoratorEventListener.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.deployment.impl;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.deployment.DeploymentEvent;
+import org.apache.jetspeed.deployment.DeploymentEventListener;
+import org.apache.jetspeed.deployment.DeploymentException;
+import org.apache.jetspeed.deployment.DeploymentStatus;
+import org.apache.jetspeed.util.DirectoryHelper;
+
+/**
+ * <p>
+ * DirectFolderEventListener
+ * </p>
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @version $Id: DeployDecoratorEventListener.java 188432 2005-03-23 22:48:43Z ate $
+ */
+public class DeployDecoratorEventListener implements DeploymentEventListener
+{
+    protected static final Log log = LogFactory.getLog("deployment");
+    protected String           deployToDir;
+
+    public DeployDecoratorEventListener(String deployToDir) throws FileNotFoundException
+    {
+        File checkFile = new File(deployToDir);
+        if (checkFile.exists())
+        {
+            try
+            {
+                this.deployToDir = checkFile.getCanonicalPath();
+            }
+            catch (IOException e) {}
+        }
+        else
+        {
+            throw new FileNotFoundException("The deployment directory, " + checkFile.getAbsolutePath()
+                                            + ", does not exist");
+        }
+    }
+
+    public void initialize()
+    {
+    // nothing to do
+    }
+
+    /**
+     * <p>
+     * invokeDeploy
+     * </p>
+     * 
+     * @see org.apache.jetspeed.deployment.DeploymentEventListener#invokeDeploy(org.apache.jetspeed.deployment.DeploymentEvent)
+     * @param event
+     * @throws DeploymentException
+     */
+    public void invokeDeploy(DeploymentEvent event) throws DeploymentException
+    {
+        String fileName = event.getName();
+        if (!fileName.endsWith(".jar") && !fileName.endsWith(".zip"))
+        {
+            return;
+        }
+
+        // get decorator configuration if available
+        PropertiesConfiguration conf = getDecoratorConfiguration(event);
+        // silently return if configuration not available, (assumes
+        // probably not a decorator)
+        if (conf == null)
+        {
+            return;
+        }
+
+        // process decorator by id
+        String id = conf.getString("id");
+        if (id == null)
+        {
+            throw new DeploymentException("Unable to deploy decorator, \"id\" attribute not defined in configuration");
+        }
+        
+        log.info("Found decorator deployment archive " + id);
+
+        try
+        {
+            // construct decorator deploy path
+            String baseDeployPath = getBaseDeployPath(conf);
+            String deployPath = baseDeployPath + File.separator + id;
+            File deployPathFile = new File(deployPath);
+
+            // undeploy decorator if it already exists and is a redeploy or
+            // skip deployment if initial deployment
+            if (deployPathFile.exists())
+            {
+                invokeUndeploy(deployPathFile);
+            }
+
+            // redeploy/deploy decorator w/o META_INF jar metadata
+            log.info("Deploying decorator " + id + " to " + deployPath);
+            JarExpander.expand(event.getDeploymentObject().getFile(), deployPathFile);
+            File metaInf = new File(deployPathFile, "META-INF");
+            if (metaInf.exists())
+            {
+                DirectoryHelper cleanup = new DirectoryHelper(metaInf);
+                cleanup.remove();
+                cleanup.close();
+            }
+
+            // detect language/country localized decorator components
+            final List localeSpecificDeployPathsList = getLocaleSpecificDeployPaths(deployPathFile);
+
+            // deploy individual locale specific decorator components
+            Iterator deployPathsIter = localeSpecificDeployPathsList.iterator();
+            while (deployPathsIter.hasNext())
+            {
+                File localeDeployPathFile = (File) deployPathsIter.next();
+
+                // deploy to locale specific location
+                File deployToPathFile = new File(baseDeployPath
+                                                 + localeDeployPathFile.getPath().substring(deployPath.length())
+                                                 + File.separator + id);
+                log.info("Deploying locale specific decorator component to " + deployToPathFile.getPath());
+                deployToPathFile.mkdirs();
+
+                // deploy decorator components by moving from deployed decorator
+                File[] filesToDeploy = localeDeployPathFile.listFiles(new FileFilter()
+                {
+                    public boolean accept(File pathname)
+                    {
+                        return !localeSpecificDeployPathsList.contains(pathname);
+                    }
+                });
+                for (int i = 0; (i < filesToDeploy.length); i++)
+                {
+                    filesToDeploy[i].renameTo(new File(deployToPathFile, filesToDeploy[i].getName()));
+                }
+            }
+
+            // cleanup locale specific deployment directories
+            Iterator cleanupDeployPathsIter = localeSpecificDeployPathsList.iterator();
+            while (cleanupDeployPathsIter.hasNext())
+            {
+                File cleanupLocaleDeployPathFile = (File) cleanupDeployPathsIter.next();
+                if (cleanupLocaleDeployPathFile.exists())
+                {
+                    DirectoryHelper cleanup = new DirectoryHelper(cleanupLocaleDeployPathFile);
+                    cleanup.remove();
+                    cleanup.close();
+                }
+            }
+
+            log.info("Decorator " + id + " deployed successfuly.");
+            event.setStatus(DeploymentStatus.STATUS_OKAY);
+        }
+        catch (DeploymentException de)
+        {
+            throw de;
+        }
+        catch (Exception e)
+        {
+            throw new DeploymentException("Error deploying decorator " + id, e);
+        }
+    }
+
+    /**
+     * <p>
+     * invokeUndeploy
+     * </p>
+     * 
+     * @throws DeploymentException
+     */
+    public void invokeUndeploy(File deployPathFile) throws DeploymentException
+    {
+
+        if (deployPathFile == null || !deployPathFile.exists() || !deployPathFile.isDirectory()
+            || deployPathFile.getParentFile() == null || deployPathFile.getParentFile().getParentFile() == null
+            || !deployToDir.equals(deployPathFile.getParentFile().getParentFile().getParent()))
+        {
+            throw new DeploymentException("Cannot undeploy decorator at " + deployPathFile + ": invalid decorator path");
+        }
+
+        String id = deployPathFile.getName();
+
+        try
+        {
+            // undeploy decorator
+            log.info("Undeploying decorator " + id + " at " + deployPathFile.getAbsolutePath());
+
+            // detect language/country localized decorator components
+            final List localeSpecificDeployPathsList = getLocaleSpecificDeployPaths(deployPathFile.getParentFile());
+
+            // undeploy individual locale specific decorator components depth first
+            for (int i = localeSpecificDeployPathsList.size() - 1; i > -1; i--)
+            {
+                File localeDeployPathFile = new File((File) localeSpecificDeployPathsList.get(i), id);
+                if (localeDeployPathFile.exists())
+                {
+                    log.info("Undeploying locale specific decorator component at " + localeDeployPathFile.getPath());
+                    DirectoryHelper cleanup = new DirectoryHelper(localeDeployPathFile);
+                    cleanup.remove();
+                    cleanup.close();
+                    localeDeployPathFile.getParentFile().delete();
+                }
+            }
+
+            // now undeploy the decorator root itself
+            DirectoryHelper cleanup = new DirectoryHelper(deployPathFile);
+            cleanup.remove();
+            cleanup.close();
+
+            log.info("Decorator " + id + " undeployed successfuly.");
+        }
+        catch (Exception e)
+        {
+            throw new DeploymentException("Error undeploying decorator " + id, e);
+        }
+    }
+
+    /**
+     * <p>
+     * getDecorationConfiguration
+     * </p>
+     * 
+     * @param event @
+     * @return configuration
+     * @throws DeploymentException
+     */
+    private PropertiesConfiguration getDecoratorConfiguration(DeploymentEvent event) throws DeploymentException
+    {
+        InputStream stream = null;
+        try
+        {
+            if (event.getDeploymentObject() == null)
+            {
+                return null;
+            }
+            stream = event.getDeploymentObject().getConfiguration("decorator.properties");
+            if (stream == null)
+            {
+                return null;
+            }
+            else
+            {
+                PropertiesConfiguration configuration = new PropertiesConfiguration();
+                configuration.load(stream);
+                return configuration;
+            }
+        }
+        catch (Exception e1)
+        {
+            throw new DeploymentException("Error reading decorator.properties from " + event.getPath(), e1);
+        }
+        finally
+        {
+            if (stream != null)
+            {
+                try
+                {
+                    stream.close();
+                }
+                catch (IOException e)
+                {
+
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * getBaseDeployPath
+     * </p>
+     * 
+     * @param configuration
+     * @return base deploy path
+     */
+    private String getBaseDeployPath(PropertiesConfiguration configuration)
+    {
+        // construct decorator deploy base path
+        String layoutType = configuration.getString("decorates", "generic");
+        if (layoutType.equalsIgnoreCase("any"))
+        {
+            layoutType = "generic";
+        }
+        String mediaType = configuration.getString("media.type", "html");
+        return deployToDir + File.separator + layoutType + File.separator + mediaType;
+    }
+
+    /**
+     * <p>
+     * getLocaleSpecificDeployPaths
+     * </p>
+     * 
+     * @param rootPath
+     * @return locale paths list
+     */
+    private List getLocaleSpecificDeployPaths(File rootPath)
+    {
+        // detect language/country localized deploy paths
+        List localeSpecificDeployPathsList = new ArrayList();
+        File[] localeLanguageSpecificRoots = rootPath.listFiles(new FileFilter()
+        {
+            public boolean accept(File pathname)
+            {
+                // filter language code dirs, (assume length test is accurate enough)
+                return (pathname.isDirectory() && (pathname.getName().length() == 2));
+            }
+        });
+        for (int i = 0; (i < localeLanguageSpecificRoots.length); i++)
+        {
+            localeSpecificDeployPathsList.add(localeLanguageSpecificRoots[i]);
+            File[] localeCountrySpecificPaths = localeLanguageSpecificRoots[i].listFiles(new FileFilter()
+            {
+                public boolean accept(File pathname)
+                {
+                    // filter country code dirs, (assume length test is accurate enough)
+                    return (pathname.isDirectory() && (pathname.getName().length() == 2));
+                }
+            });
+            for (int j = 0; (j < localeCountrySpecificPaths.length); j++)
+            {
+                localeSpecificDeployPathsList.add(localeCountrySpecificPaths[j]);
+            }
+        }
+        return localeSpecificDeployPathsList;
+    }
+}
\ No newline at end of file

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployPortletAppEventListener.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployPortletAppEventListener.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployPortletAppEventListener.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeployPortletAppEventListener.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.deployment.impl;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.components.portletregistry.PortletRegistry;
+import org.apache.jetspeed.deployment.DeploymentEvent;
+import org.apache.jetspeed.deployment.DeploymentEventListener;
+import org.apache.jetspeed.deployment.DeploymentException;
+import org.apache.jetspeed.deployment.DeploymentStatus;
+import org.apache.jetspeed.tools.deploy.JetspeedDeploy;
+import org.apache.jetspeed.tools.pamanager.PortletApplicationManagement;
+import org.apache.jetspeed.util.DirectoryHelper;
+
+/**
+ * <p>
+ * DeployportletAppEventListener
+ * </p>
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
+ * @version $Id: DeployPortletAppEventListener.java 188608 2005-05-24 18:54:01Z ate $
+ */
+public class DeployPortletAppEventListener implements DeploymentEventListener
+{
+
+    protected static final Log           log = LogFactory.getLog("deployment");
+    private String                       webAppDir;
+    private String                       localAppDir;
+    private boolean                      stripLoggers;
+    private PortletApplicationManagement pam;
+    private PortletRegistry              registry;
+
+    /**
+     * @param pam
+     * @param webAppDir
+     * @param localAppDir
+     * @throws FileNotFoundException the <code>webAppDir</code> or <code>localAppDir</code> directory does not
+     *                               exist.
+     */
+    public DeployPortletAppEventListener(PortletApplicationManagement pam, PortletRegistry registry, String webAppDir,
+                                         String localAppDir, boolean stripLoggers) throws FileNotFoundException
+    {
+        this.pam = pam;
+        this.registry = registry;
+        this.stripLoggers = stripLoggers;
+
+        File webAppDirFile = new File(webAppDir);
+
+        if (webAppDirFile.exists())
+        {
+            try
+            {
+                this.webAppDir = webAppDirFile.getCanonicalPath();
+            }
+            catch (IOException e) {}
+        }
+        else
+        {
+            throw new FileNotFoundException("The depoyment directory for portlet applications \""
+                                            + webAppDirFile.getAbsolutePath() + "\" does not exist.");
+        }
+        File localAppDirFile = new File(localAppDir);
+
+        if (!localAppDirFile.exists())
+        {
+            localAppDirFile.mkdirs();
+        }
+        else if (!localAppDirFile.isDirectory())
+        {
+            throw new FileNotFoundException("Invalid depoyment directory for local portlet applications: \""
+                                            + localAppDirFile.getAbsolutePath());
+        }
+        try
+        {
+            this.localAppDir = localAppDirFile.getCanonicalPath();
+        }
+        catch (IOException e) {}
+    }
+
+    public void initialize()
+    {
+        // start deployed local pa
+        File[] localApps = new File(localAppDir).listFiles(new FileFilter()
+        {
+            public boolean accept(File pathname)
+            {
+                return pathname.isDirectory();
+            }
+        });
+        for (int i = 0; i < localApps.length; i++)
+        {
+            // Check for at least WEB-INF/portlet.xml
+            // This will also prevent the src/webapps/WEB-INF/apps/CVS folder
+            // to be seen as local app from testcases resulting in an exception
+            if ( ! new File(localApps[i],"WEB-INF/portlet.xml").exists() )
+            {
+                log.warn("Not a local application " + localApps[i].getName());
+            }
+            else
+            {
+                DirectoryHelper paDirHelper = new DirectoryHelper(localApps[i]);
+                try
+                {
+                    pam.startLocalPortletApplication(localApps[i].getName(), paDirHelper,
+                                                     createLocalPAClassLoader(localApps[i]));
+                }
+                catch (Exception e)
+                {
+                    log.error("Failed to start Local Portlet Application " + localApps[i], e);
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * invokeDeploy
+     * </p>
+     * 
+     * @param event
+     * @throws DeploymentException
+     */
+    public void invokeDeploy(DeploymentEvent event) throws DeploymentException
+    {
+        String fileName = event.getName();
+        if (fileName.endsWith(".war"))
+        {
+            int prefixLength = PortletApplicationManagement.LOCAL_PA_PREFIX.length();
+            if (fileName.length() > prefixLength
+                && fileName.substring(0, prefixLength).equalsIgnoreCase(PortletApplicationManagement.LOCAL_PA_PREFIX))
+            {
+                deployLocalPortletApplication(event);
+            }
+            else
+            {
+                deployPortletApplication(event);
+            }
+        }
+    }
+
+    protected void deployPortletApplication(DeploymentEvent event) throws DeploymentException
+    {
+        try
+        {
+            File toFile = new File(webAppDir, event.getName());
+            new JetspeedDeploy(event.getPath(), toFile.getAbsolutePath(), stripLoggers);
+            event.setStatus(DeploymentStatus.STATUS_OKAY);
+        }
+        catch (Exception e)
+        {
+            throw new DeploymentException(e);
+        }
+    }
+
+    protected void deployLocalPortletApplication(DeploymentEvent event) throws DeploymentException
+    {
+        try
+        {
+            String fileName = event.getName();
+            String appName = fileName.substring(0, fileName.length() - 4);
+            pam.stopLocalPortletApplication(appName);
+            File targetDir = new File(localAppDir, appName);
+            JarExpander.expand(event.getDeploymentObject().getFile(), targetDir);
+            DirectoryHelper paDirHelper = new DirectoryHelper(targetDir);
+            pam.startLocalPortletApplication(appName, paDirHelper, createLocalPAClassLoader(targetDir));
+            event.setStatus(DeploymentStatus.STATUS_OKAY);
+        }
+        catch (Exception e)
+        {
+            throw new DeploymentException(e);
+        }
+    }
+
+    protected ClassLoader createLocalPAClassLoader(File paDir) throws IOException
+    {
+        ArrayList urls = new ArrayList();
+        File webInfClasses = null;
+
+        webInfClasses = new File(paDir, ("WEB-INF/classes/"));
+        if (webInfClasses.exists())
+        {
+            log.info("Adding " + webInfClasses.toURL() + " to class path for Local PA " + paDir.getName());
+            urls.add(webInfClasses.toURL());
+        }
+
+        File webInfLib = new File(paDir, "WEB-INF/lib");
+
+        if (webInfLib.exists())
+        {
+            File[] jars = webInfLib.listFiles();
+
+            for (int i = 0; i < jars.length; i++)
+            {
+                File jar = jars[i];
+                log.info("Adding " + jar.toURL() + " to class path for Local PA " + paDir.getName());
+                urls.add(jar.toURL());
+            }
+        }
+        return new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]), getClass().getClassLoader());
+    }
+
+}
\ No newline at end of file

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeploymentEventImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeploymentEventImpl.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeploymentEventImpl.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/DeploymentEventImpl.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.deployment.impl;
+
+import org.apache.jetspeed.deployment.DeploymentEvent;
+import org.apache.jetspeed.deployment.DeploymentObject;
+
+
+/**
+ * <p>
+ * DeploymentEventImpl
+ * </p>
+ * 
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
+ * @version $Id: DeploymentEventImpl.java 188432 2005-03-23 22:48:43Z ate $
+ *
+ */
+public class DeploymentEventImpl implements DeploymentEvent
+{
+	private DeploymentObject handler;
+	private String deploymentRoot;
+	private int status = STATUS_EVAL;
+	protected String name;
+	protected String path;
+	
+
+    /**
+     * 
+     */
+    public DeploymentEventImpl(DeploymentObject handler, String depRoot)
+    {
+        super();
+        this.handler = handler;
+        this.deploymentRoot = depRoot;
+        this.name = handler.getName();
+		this.path = handler.getPath();       
+    }
+    
+	public DeploymentEventImpl(DeploymentObject handler)
+	{
+		super();
+		this.handler = handler;
+		this.name = handler.getName();
+		this.path = handler.getPath();
+	}
+	
+	public DeploymentEventImpl(String name, String path)
+	{
+		super();
+		this.name = name;
+		this.path = path;
+	}
+
+    /**
+     * @see org.apache.jetspeed.deployment.DeploymentEvent#getDeploymentObject()
+     */
+    public DeploymentObject getDeploymentObject()
+    {        
+        return handler;
+    }
+
+    /**
+     * @return
+     */
+    public int getStatus()
+    {
+        return status;
+    }
+
+    /**
+     * @param i
+     */
+    public void setStatus(int i)
+    {
+        status = i;
+    }
+
+    /**
+     * <p>
+     * getName
+     * </p>
+     *
+     * @see org.apache.jetspeed.deployment.DeploymentEvent#getName()
+     * @return
+     */
+    public String getName()
+    {
+        return name;
+    }
+    /**
+     * <p>
+     * getPath
+     * </p>
+     *
+     * @see org.apache.jetspeed.deployment.DeploymentEvent#getPath()
+     * @return
+     */
+    public String getPath()
+    {
+        return path;
+    }
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/FileNotDeployableException.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/FileNotDeployableException.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/FileNotDeployableException.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/FileNotDeployableException.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.deployment.impl;
+
+import org.apache.jetspeed.deployment.DeploymentException;
+
+
+/**
+ * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
+ *
+ * TODO To change the template for this generated type comment go to
+ * 
+ * Thrown when attempting to deploy a file that cannot be deployed.
+ */
+public class FileNotDeployableException extends DeploymentException
+{
+
+    /**
+     * 
+     */
+    public FileNotDeployableException()
+    {
+        super();
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param message
+     */
+    public FileNotDeployableException( String message )
+    {
+        super(message);
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param nested
+     */
+    public FileNotDeployableException( Throwable nested )
+    {
+        super(nested);
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * @param msg
+     * @param nested
+     */
+    public FileNotDeployableException( String msg, Throwable nested )
+    {
+        super(msg, nested);
+        // TODO Auto-generated constructor stub
+    }
+
+}

Added: portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/JarExpander.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/JarExpander.java?rev=209328&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/JarExpander.java (added)
+++ portals/jetspeed-2/trunk/components/portal/src/java/org/apache/jetspeed/deployment/impl/JarExpander.java Tue Jul  5 14:55:37 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.deployment.impl;
+
+import org.apache.jetspeed.util.DirectoryHelper;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * JarExpander
+ * 
+ * @author <a href="mailto:ate@douma.nu">Ate Douma </a>
+ * @version $Id: JarExpander.java 188432 2005-03-23 22:48:43Z ate $
+ */
+public class JarExpander
+{
+    public static void expand(File srcFile, File targetDir) throws IOException
+    {
+        if (targetDir.exists())
+        {
+            DirectoryHelper cleanup = new DirectoryHelper(targetDir);
+            cleanup.remove();
+            cleanup.close();
+        }
+
+        targetDir.mkdirs();
+        JarFile jarFile = new JarFile(srcFile);
+        
+        try
+        {
+            Enumeration entries = jarFile.entries();
+
+            InputStream is = null;
+            OutputStream os = null;
+
+            byte[] buf = new byte[1024];
+            int len;
+
+            while (entries.hasMoreElements())
+            {
+                JarEntry jarEntry = (JarEntry) entries.nextElement();
+                String name = jarEntry.getName();
+                File entryFile = new File(targetDir, name);
+
+                if (jarEntry.isDirectory())
+                {
+                    entryFile.mkdir();
+                }
+                else
+                {
+                    if (!entryFile.getParentFile().exists())
+                    {
+                        entryFile.getParentFile().mkdirs();
+                    }
+
+                    entryFile.createNewFile();
+
+                    try
+                    {
+                        is = jarFile.getInputStream(jarEntry);
+                        os = new FileOutputStream(entryFile);
+
+                        while ((len = is.read(buf)) > 0)
+                        {
+                            os.write(buf, 0, len);
+                        }
+                    }
+                    finally
+                    {
+                        if (is != null)
+                        {
+                            is.close();
+                        }
+
+                        if (os != null)
+                        {
+                            os.close();
+                        }
+                    }
+                }
+            }
+        }
+        finally
+        {
+            if (jarFile != null)
+            {
+                jarFile.close();
+            }
+        }
+    }
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message