You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2005/09/01 11:10:38 UTC

svn commit: r265679 [2/12] - in /cocoon/blocks/portal-sample/trunk: ./ WEB-INF/ WEB-INF/xconf/ conf/ java/ java/org/ java/org/apache/ java/org/apache/cocoon/ java/org/apache/cocoon/portal/ java/org/apache/cocoon/portal/coplets/ java/org/apache/cocoon/p...

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.cocoon.portal.LinkService;
+import org.apache.cocoon.portal.PortalService;
+import org.apache.cocoon.portal.coplets.basket.events.CleanBriefcaseEvent;
+import org.apache.cocoon.portal.coplets.basket.events.RefreshBasketEvent;
+import org.apache.cocoon.portal.coplets.basket.events.RemoveItemEvent;
+import org.apache.cocoon.portal.coplets.basket.events.ShowBasketEvent;
+import org.apache.cocoon.portal.coplets.basket.events.ShowItemEvent;
+import org.apache.cocoon.portal.event.Event;
+import org.apache.cocoon.portal.profile.ProfileManager;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.xml.sax.SAXException;
+
+/**
+ * This is a portlet that displays the contents of a basket
+ *
+ * @version CVS $Id$
+ */
+public class BasketGenerator
+extends ServiceableGenerator {
+    
+    /** This is the coplet ID that is used to display the content */
+    protected String showCopletId;
+    
+    /** This is the layout ID that is used to display the content */
+    protected String showLayoutId;
+
+    /** The type of items to display */
+    protected String type;
+    
+    /** The location of the type information */
+    protected String typeLocation;
+    
+    /** admin mode? */
+    protected boolean adminMode;
+    
+    /** The basket manager */
+    protected BasketManager basketManager;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.basketManager = (BasketManager)this.manager.lookup(BasketManager.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release(this.basketManager);
+            this.basketManager = null;
+        }
+        super.dispose();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver resolver,
+                      Map objectModel,
+                      String src,
+                      Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        this.showCopletId = par.getParameter("show-coplet", null);
+        this.showLayoutId = par.getParameter("show-layout", null);
+        this.adminMode = par.getParameterAsBoolean("admin-mode", false);
+        this.type = par.getParameter("type", null);
+        this.typeLocation = par.getParameter("type-location", null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.generation.Generator#generate()
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+        this.xmlConsumer.startDocument();
+        if ( this.adminMode ) {
+            this.generateAdminMode();            
+        } else {
+            PortalService service = null;
+            try {
+                service = (PortalService)this.manager.lookup(PortalService.ROLE);
+
+                final UserConfiguration uc = UserConfiguration.get(this.objectModel, service);
+                Basket    basket = null;
+                Briefcase briefcase = null;
+                Folder    folder = null;
+
+                if ( uc.isBasketEnabled() ) {
+                    basket = this.basketManager.getBasket();
+                }
+                if ( uc.isBriefcaseEnabled() ) {
+                    briefcase = this.basketManager.getBriefcase();
+                }
+                if ( uc.isFolderEnabled() ) {
+                    folder = this.basketManager.getFolder();
+                }
+    
+                final LinkService linkService = service.getComponentManager().getLinkService();
+                
+                XMLUtils.startElement(this.xmlConsumer, "basket-content");
+    
+                this.toSAX(uc);
+                
+                final ProfileManager profileManager = service.getComponentManager().getProfileManager();
+                    
+                    XMLUtils.startElement(this.xmlConsumer, "items");
+                
+                int itemCount = 0;
+                long itemSize = 0;
+
+                StoreInfo info;
+                
+                info = this.toSAX(basket, linkService, profileManager);
+                itemCount += info.count;
+                itemSize += info.maxSize;
+                info = this.toSAX(briefcase, linkService, profileManager);
+                itemCount += info.count;
+                itemSize += info.maxSize;
+                info = this.toSAX(folder, linkService, profileManager);
+                itemCount += info.count;
+                itemSize += info.maxSize;
+
+                XMLUtils.endElement(this.xmlConsumer, "items");
+
+                XMLUtils.startElement(this.xmlConsumer, "item-count");
+                XMLUtils.data(this.xmlConsumer, String.valueOf(itemCount));
+                XMLUtils.endElement(this.xmlConsumer, "item-count");
+
+                XMLUtils.startElement(this.xmlConsumer, "item-size");
+                double f = itemSize / 10.24;
+                f = Math.floor(f);
+                if ( f < 10.0 && f > 0.1) {
+                    f = 10.0;
+                } else if ( f < 0.1 ) {
+                    f = 0.0;
+                }
+                f = f / 100.0;
+                XMLUtils.data(this.xmlConsumer, String.valueOf(f));
+                XMLUtils.endElement(this.xmlConsumer, "item-size");
+
+                XMLUtils.endElement(this.xmlConsumer, "basket-content");
+            } catch (ServiceException se) {
+                throw new SAXException("Unable to lookup portal service.", se);
+            } finally {
+                this.manager.release(service);
+            }
+        }
+        this.xmlConsumer.endDocument();
+    }
+
+    /**
+     * Render admin mode
+     */
+    protected void generateAdminMode() 
+    throws SAXException {
+        List baskets = this.basketManager.getBriefcaseDescriptions();
+
+        PortalService service = null;
+        try {
+            service = (PortalService)this.manager.lookup(PortalService.ROLE);
+            LinkService linkService = service.getComponentManager().getLinkService();
+            XMLUtils.startElement(this.xmlConsumer, "basket-admin");
+            if ( baskets.size() > 0 ) {
+                XMLUtils.startElement(this.xmlConsumer, "baskets");
+                for(int i=0; i<baskets.size();i++) {
+                    ContentStoreDescription item = (ContentStoreDescription)baskets.get(i);
+                    XMLUtils.startElement(this.xmlConsumer, "basket");
+
+                    XMLUtils.startElement(this.xmlConsumer, "id");
+                    XMLUtils.data(this.xmlConsumer, item.id);
+                    XMLUtils.endElement(this.xmlConsumer, "id");
+                    
+                    XMLUtils.startElement(this.xmlConsumer, "size");
+                    XMLUtils.data(this.xmlConsumer, String.valueOf(item.size));
+                    XMLUtils.endElement(this.xmlConsumer, "size");
+                    
+                    Event event = new CleanBriefcaseEvent((Briefcase)null);
+                    XMLUtils.startElement(this.xmlConsumer, "remove-url");
+                    XMLUtils.data(this.xmlConsumer, linkService.getLinkURI(event));
+                    XMLUtils.endElement(this.xmlConsumer, "remove-url");
+                    
+                    event = new ShowBasketEvent(item.id);
+                    XMLUtils.startElement(this.xmlConsumer, "show-url");
+                    XMLUtils.data(this.xmlConsumer, linkService.getLinkURI(event));
+                    XMLUtils.endElement(this.xmlConsumer, "show-url");
+
+                    XMLUtils.endElement(this.xmlConsumer, "basket");
+                }
+                XMLUtils.endElement(this.xmlConsumer, "baskets");
+            }
+            Event e;
+            e = new RefreshBasketEvent();
+            XMLUtils.startElement(this.xmlConsumer, "refresh-url");
+            XMLUtils.data(this.xmlConsumer, linkService.getLinkURI(e));
+            XMLUtils.endElement(this.xmlConsumer, "refresh-url");
+            
+            e = new CleanBriefcaseEvent();
+            XMLUtils.startElement(this.xmlConsumer, "clean-url");
+            XMLUtils.data(this.xmlConsumer, linkService.getLinkURI(e));
+            XMLUtils.endElement(this.xmlConsumer, "clean-url");
+            
+            XMLUtils.endElement(this.xmlConsumer, "basket-admin");
+        } catch (ServiceException se) {
+            throw new SAXException("Unable to lookup portal service.", se);
+        } finally {
+            this.manager.release(service);
+        }
+    }
+    
+    protected StoreInfo toSAX(ContentStore store, LinkService linkService, ProfileManager profileManager)
+    throws SAXException {
+        StoreInfo info = new StoreInfo();
+        if ( store != null ) {
+            for(int i=0; i<store.size();i++) {
+                Object item = store.getItem(i);
+                if ( item instanceof ContentItem ) {
+                    ContentItem ci = (ContentItem)item;
+                    
+                    boolean process = true;
+                    if ( this.type != null && this.type.length() > 0 && this.typeLocation != null ) {
+                        Map attributes = (Map)ci.getAttribute("coplet-attributes");
+                        if ( attributes != null ) {
+                            if ( !this.type.equals(attributes.get(this.typeLocation)) ) {
+                                process = false;
+                            }
+                        }
+                    }
+                    if ( process ) {
+                        info.count++;
+                        info.maxSize += ci.size();
+                        XMLUtils.startElement(this.xmlConsumer, "item");
+                        
+                        XMLUtils.createElement(this.xmlConsumer, "title", item.toString());
+        
+                        XMLUtils.startElement(this.xmlConsumer, "store");
+                        if ( store instanceof Briefcase ) {
+                            XMLUtils.data(this.xmlConsumer, "briefcase");
+                        } else if ( store instanceof Folder ) {
+                            XMLUtils.data(this.xmlConsumer, "folder");                    
+                        } else {
+                            XMLUtils.data(this.xmlConsumer, "basket");                    
+                        }
+                        XMLUtils.endElement(this.xmlConsumer, "store");
+                    
+                        XMLUtils.createElement(this.xmlConsumer, "id", String.valueOf(ci.getId()));
+                        Event e = new ShowItemEvent(store, item, profileManager.getPortalLayout(null, this.showLayoutId), this.showCopletId);
+                        XMLUtils.createElement(this.xmlConsumer, "show-url", linkService.getLinkURI(e));
+                        if (ci.size() != -1 ) {
+                            XMLUtils.createElement(this.xmlConsumer, "size", String.valueOf(ci.size()));
+                        }                        
+                        XMLUtils.startElement(this.xmlConsumer, "attributes");
+                        this.toSAX(ci.attributes);
+                        XMLUtils.endElement(this.xmlConsumer, "attributes");
+                        Event removeEvent = new RemoveItemEvent(store, item);
+                        XMLUtils.createElement(this.xmlConsumer, "remove-url", linkService.getLinkURI(removeEvent));
+                        
+                        XMLUtils.endElement(this.xmlConsumer, "item");
+                    }
+                }
+            }
+        }    
+        return info;
+    }
+    
+    protected void toSAX(Map attributes)
+    throws SAXException {
+        if ( attributes != null ) {
+            AttributesImpl a = new AttributesImpl();
+            final Iterator i = attributes.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry current = (Map.Entry)i.next();
+                final String key = current.getKey().toString();
+                if ( "coplet-attributes".equals(key) ) {
+                    this.toSAX((Map)current.getValue());
+                } else {
+                    final Object value = current.getValue();
+                    final String valueText;
+                    if ( value != null ) {
+                        valueText = value.toString();
+                    } else {
+                        valueText ="";
+                    }
+                    a.addCDATAAttribute("name", key);
+                    a.addCDATAAttribute("value", valueText);
+                    XMLUtils.createElement(this.xmlConsumer, "attribute", a);
+                    a.clear();
+                }
+            }
+        }
+    }
+    
+    protected void toSAX(UserConfiguration uc)
+    throws SAXException {
+        XMLUtils.startElement(this.xmlConsumer, "configuration");
+        AttributesImpl attr = new AttributesImpl();
+        
+        if ( uc.isBasketEnabled() ) {
+            XMLUtils.createElement(this.xmlConsumer, "basket", attr, "enabled");
+            attr.clear();
+        }
+        if ( uc.isBriefcaseEnabled() ) {
+            XMLUtils.createElement(this.xmlConsumer, "briefcase", "enabled");
+            attr.clear();
+        }
+        if ( uc.isFolderEnabled() ) {
+            XMLUtils.createElement(this.xmlConsumer, "folder", "enabled");
+            attr.clear();
+        }
+        
+        XMLUtils.endElement(this.xmlConsumer, "configuration");
+    }
+    
+    public static final class StoreInfo {
+        int count;
+        long maxSize;
+    }
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.util.List;
+
+/**
+ * This is the manager for content-stores: baskets, briefcases and folders
+ * You can retrieve the current basket, briefcase or folder for the user 
+ * from this manager.
+ *
+ * @version CVS $Id$
+ */
+public interface BasketManager {
+    
+    /** The component role */
+    String ROLE = BasketManager.class.getName();
+    
+    /** This key is used to store the current basket in the session */
+    String BASKET_KEY = BasketManager.class.getName() + "/Basket";
+
+    /** This key is used to store the current briefcase in the session */
+    String BRIEFCASE_KEY = BasketManager.class.getName() + "/Briefcase";
+
+    /** This key is used to store the current folder in the session */
+    String FOLDER_KEY = BasketManager.class.getName() + "/Folder";
+
+    /** This key is used to store all briefcases in the session (of the admin) */
+    String ALL_BRIEFCASES_KEY = BasketManager.class.getName() + "/All";
+
+    /**
+     * Return the basket of the current user
+     */
+    Basket getBasket();
+   
+    /**
+     * Return the briefcase of the current user
+     */
+    Briefcase getBriefcase();
+
+    /**
+     * Return the folder of the current user
+     */
+    Folder getFolder();
+
+    /**
+     * Return all briefcases. 
+     * This is a list of {@link ContentStoreDescription} objects.
+     */
+    List getBriefcaseDescriptions();
+
+    /** 
+     * An action info consists of a name and a url
+     */
+    public static class ActionInfo {
+        public final String name;
+        public final String url;
+        
+        public ActionInfo(String n, String u) {
+            this.name = n;
+            this.url = u;
+        }
+    }
+
+    /**
+     * Return all configured actions for a basket - this is a list of 
+     * {@link #ActionInfo}s.
+     */
+    List getBasketActions();
+
+    /**
+     * Get the info
+     */
+    ActionInfo getBasketAction(String name);
+    
+    /**
+     * Return all configured actions for a briefcase - this is a list of 
+     * {@link #ActionInfo}s.
+     */
+    List getBriefcaseActions();
+
+    /**
+     * Get the info
+     */
+    ActionInfo getBriefcaseAction(String name);
+
+    void addBatch(ContentItem item,
+                  int         frequencyInDays,
+                  ActionInfo  action);
+    
+    /**
+     * Update/save the content store
+     */
+    void update(ContentStore store);
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,868 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.io.IOUtil;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.cron.CronJob;
+import org.apache.cocoon.components.cron.JobScheduler;
+import org.apache.cocoon.components.cron.ServiceableCronJob;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.portal.PortalService;
+import org.apache.cocoon.portal.coplet.CopletData;
+import org.apache.cocoon.portal.coplet.CopletInstanceData;
+import org.apache.cocoon.portal.coplets.basket.events.AddItemEvent;
+import org.apache.cocoon.portal.coplets.basket.events.ContentStoreEvent;
+import org.apache.cocoon.portal.coplets.basket.events.CleanBriefcaseEvent;
+import org.apache.cocoon.portal.coplets.basket.events.MoveItemEvent;
+import org.apache.cocoon.portal.coplets.basket.events.RefreshBasketEvent;
+import org.apache.cocoon.portal.coplets.basket.events.RemoveItemEvent;
+import org.apache.cocoon.portal.coplets.basket.events.ShowBasketEvent;
+import org.apache.cocoon.portal.coplets.basket.events.ShowItemEvent;
+import org.apache.cocoon.portal.coplets.basket.events.UploadItemEvent;
+import org.apache.cocoon.portal.event.EventManager;
+import org.apache.cocoon.portal.event.Receiver;
+import org.apache.cocoon.portal.layout.impl.CopletLayout;
+import org.apache.cocoon.servlet.multipart.Part;
+import org.apache.cocoon.servlet.multipart.PartOnDisk;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * This is the implementation of the basket manager
+ *
+ * @version CVS $Id$
+ */
+public class BasketManagerImpl
+extends AbstractLogEnabled
+implements BasketManager, Serviceable, Receiver, Contextualizable, Initializable, Disposable, Parameterizable, ThreadSafe  {
+    
+    /** The service manager */
+    protected ServiceManager manager;
+    
+    /** The component context */
+    protected Context context;
+    
+    /** The configuration for storing baskets */
+    protected String directory;
+    
+    /** The class name of the basket */
+    protected String basketClassName = Basket.class.getName();
+    
+    /** The class name of the briefcase */
+    protected String briefcaseClassName = Briefcase.class.getName();
+
+    /** The class name of the folder */
+    protected String folderClassName = Folder.class.getName();
+
+    /** All actions for a basket */
+    protected List basketActions = new ArrayList();
+    
+    /** All actions for a briefcase */
+    protected List briefcaseActions = new ArrayList();
+    
+    /** All batches */
+    protected List batches = new ArrayList();
+    
+    /** Scheduler */
+    protected JobScheduler scheduler;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+        this.directory = parameters.getParameter("directory", this.directory);
+        this.basketClassName = parameters.getParameter("basket-class", this.basketClassName);
+        this.briefcaseClassName = parameters.getParameter("briefcase-class", this.briefcaseClassName);
+        this.folderClassName = parameters.getParameter("folder-class", this.folderClassName);
+        String[] names = parameters.getNames();
+        if ( names != null ) {
+            for(int i=0; i<names.length; i++) {
+                final String current = names[i];
+                if ( current.startsWith("basket:action:") ) {
+                    final String value = parameters.getParameter(current);
+                    final String key = current.substring(14);
+                    this.basketActions.add(new ActionInfo(key, value));
+                } else if ( current.startsWith("briefcase:action:") ) {
+                    final String value = parameters.getParameter(current);
+                    final String key = current.substring(17);
+                    this.briefcaseActions.add(new ActionInfo(key, value));
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+        this.directory = ((File)context.get(Constants.CONTEXT_WORK_DIR)).getAbsolutePath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.scheduler = (JobScheduler)this.manager.lookup(JobScheduler.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release(this.scheduler);
+            this.scheduler = null;
+            this.manager = null;
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        EventManager eventManager = null;
+        try {
+            eventManager = (EventManager) this.manager.lookup(EventManager.ROLE);
+            eventManager.subscribe(this);
+        } finally {
+            this.manager.release(eventManager);
+        }
+    }
+
+    /**
+     * @see Receiver
+     */
+    public void inform(ContentStoreEvent event, PortalService service) {
+        // dispatch
+        final Session session = ContextHelper.getRequest(this.context).getSession();
+        if ( event instanceof AddItemEvent ) {
+            
+            this.processAddItemEvent((AddItemEvent)event);
+            
+        } else if (event instanceof RemoveItemEvent ){
+            
+            this.processRemoveItemEvent((RemoveItemEvent)event);
+            
+        } else if (event instanceof RefreshBasketEvent) {
+            
+            session.removeAttribute(ALL_BRIEFCASES_KEY);          
+            
+        } else if (event instanceof CleanBriefcaseEvent) {
+            
+            this.processCleanBriefcaseEvent((CleanBriefcaseEvent)event, session);
+            
+        } else if ( event instanceof UploadItemEvent ) {
+            
+            this.processUploadItemEvent((UploadItemEvent)event);
+        } else if ( event instanceof ShowItemEvent ) {
+            
+            this.processShowItemEvent((ShowItemEvent)event);
+        } else if ( event instanceof ShowBasketEvent ) {
+            
+            this.processShowBasketEvent((ShowBasketEvent)event, session);
+        } else if ( event instanceof MoveItemEvent ) {
+            ContentStore source = ((MoveItemEvent)event).getContentStore();
+            ContentStore target = ((MoveItemEvent)event).getTarget();
+            Object item = ((MoveItemEvent)event).getItem();
+            source.removeItem(item);
+            target.addItem(item);
+            this.saveContentStore(source);
+            this.saveContentStore(target);
+        }
+    }
+
+    /**
+     * Process an upload and add the item to the content store
+     * @param event The event triggering the action
+     */
+    protected void processUploadItemEvent(UploadItemEvent event) {
+        final ContentStore store = event.getContentStore();
+        final Request req = ContextHelper.getRequest(this.context);
+        final List paramNames = event.getItemNames();
+        final Iterator i = paramNames.iterator();
+        while ( i.hasNext() ) {
+            final String name = (String)i.next();
+            final Object o = req.get(name);
+            if ( o != null && o instanceof Part) {
+                final Part file = (Part)o;
+                try {
+                    byte[] c = IOUtil.toByteArray(file.getInputStream());
+                    ContentItem ci = new ContentItem(file.getFileName(), true);
+                    ci.setContent(c);
+                    store.addItem(ci);
+                } catch (Exception ignore) {
+                    // ignore the exception
+                }
+                if ( file instanceof PartOnDisk) {
+                    ((PartOnDisk)file).getFile().delete();
+                }
+            }
+        }
+    }
+
+    /**
+     * Show one item of the basket
+     * @param event  The event triggering the action
+     * @param basket The basket
+     */
+    protected void processShowItemEvent(ShowItemEvent event) {
+        if ( event.getItem() instanceof ContentItem ) {
+            PortalService service = null;
+            try {
+                service = (PortalService) this.manager.lookup(PortalService.ROLE);
+                
+                ContentItem ci = (ContentItem)event.getItem();
+                CopletLayout layout = (CopletLayout) event.getLayout();
+                CopletInstanceData cid = null;
+                if ( ci.isContent() ) {
+                    CopletData copletData = service.getComponentManager().getProfileManager().getCopletData(event.getCopletDataId());
+                    cid = service.getComponentManager().getCopletFactory().newInstance(copletData);
+                    cid.setAttribute("item-content", ci.getContent());                
+                } else {
+                    if ( ci.getURL() != null ) {
+                        SourceResolver resolver = null;
+                        Source source = null;
+                        String url = null;
+                        try {
+                            resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+                            url = ci.getURL();
+                            source = resolver.resolveURI(url);
+                            CopletData copletData = service.getComponentManager().getProfileManager().getCopletData(event.getCopletDataId());
+                            cid = service.getComponentManager().getCopletFactory().newInstance(copletData);
+                            cid.setAttribute("item-content", IOUtil.toByteArray(source.getInputStream()));
+                        } catch (IOException se) {
+                            this.getLogger().warn("Unable to get content for " + url, se);
+                        } catch (ServiceException se) {
+                            this.getLogger().warn("Unable to get source resolver.", se);
+                        } finally {
+                            if ( source != null ) {
+                                resolver.release(source);
+                            }
+                            this.manager.release(resolver);
+                        }
+                        
+                    } else {
+                        final CopletInstanceData original = service.getComponentManager().getProfileManager().getCopletInstanceData(ci.getCopletId());
+                        final CopletData copletData = original.getCopletData();
+                        cid = service.getComponentManager().getCopletFactory().newInstance(copletData);
+                        Map attributes = (Map) ci.getAttribute("coplet-attributes");
+                        Iterator i = attributes.entrySet().iterator();
+                        while ( i.hasNext() ) {
+                            Map.Entry entry = (Map.Entry)i.next();
+                            cid.setAttribute(entry.getKey().toString(), entry.getValue());
+                        }
+                        // now copy the original attributes
+                        attributes = original.getAttributes();
+                        i = attributes.entrySet().iterator();
+                        while ( i.hasNext() ) {
+                            Map.Entry entry = (Map.Entry)i.next();
+                            cid.setAttribute(entry.getKey().toString(), entry.getValue());
+                        }
+                    }
+                }
+                layout.setCopletInstanceData(cid);
+            } catch (ProcessingException pe) {
+                this.getLogger().warn("Unable to create new instance.", pe);
+            } catch (ServiceException se) {
+                this.getLogger().warn("Unable to lookup portal service.", se);
+            } finally {
+                this.manager.release(service);
+            }
+        }
+    }
+
+    /**
+     * Show the selected basket
+     */
+    protected void processShowBasketEvent(ShowBasketEvent event, Session session) {
+        Briefcase briefcase = (Briefcase)this.loadContentStore( BRIEFCASE_KEY, event.getBasketId() );
+        session.setAttribute(BRIEFCASE_KEY, briefcase);
+    }
+    
+    /**
+     * Cleaning a briefcase or all
+     * @param event   The triggering event
+     * @param session The session
+     */
+    protected void processCleanBriefcaseEvent(CleanBriefcaseEvent event, Session session) {
+        final Briefcase briefcase = (Briefcase)event.getContentStore();
+        final List baskets = (List)session.getAttribute(ALL_BRIEFCASES_KEY);
+        if ( briefcase == null) {
+            // remove all briefcases
+            if ( baskets != null ) {
+                Iterator i = baskets.iterator();
+                while (i.hasNext()) {
+                    ContentStoreDescription entry = (ContentStoreDescription)i.next();
+                    this.deleteContentStore(BRIEFCASE_KEY, entry.id);
+                }
+                session.removeAttribute(ALL_BRIEFCASES_KEY);
+            }
+        } else {
+            // remove one briefcase
+            this.deleteContentStore(BRIEFCASE_KEY, briefcase.getId());
+            if ( baskets != null ) {
+                Iterator i = baskets.iterator();
+                boolean found = false;
+                while (i.hasNext() && !found) {
+                    ContentStoreDescription entry = (ContentStoreDescription)i.next();
+                    if ( entry.id.equals(briefcase.getId())) {
+                        found = true;
+                        i.remove();
+                    }
+                }                    
+            }
+        }
+    }
+
+    /**
+     * This method processes removing one item from a content store
+     * @param event The event triggering the action
+     */
+    protected void processRemoveItemEvent(RemoveItemEvent event) {
+        final Object item = event.getItem();
+        final ContentStore store = event.getContentStore();
+        
+        store.removeItem(item);
+        
+        this.saveContentStore(store);
+    }
+
+    /**
+     * This method processes adding one item to a content store
+     * @param event The event triggering the action
+     */
+    protected void processAddItemEvent(AddItemEvent event) {
+        final ContentStore store = event.getContentStore();
+        final Object item = event.getItem();
+        if ( item instanceof ContentItem ) {
+            ContentItem ci = (ContentItem)item;
+
+                if ( ci.isContent() ) {
+                    SourceResolver resolver = null;
+                    Source source = null;
+                    String url = null;
+                    try {
+                        resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+                        url = ci.getURL();
+                        if ( url == null ) {
+                        // copy coplet attributes
+                        PortalService service = null;
+                        try {
+                            service = (PortalService) this.manager.lookup(PortalService.ROLE);
+                            CopletInstanceData cid = service.getComponentManager().getProfileManager().getCopletInstanceData(ci.getCopletId());
+                            url = "coplet://" + ci.getCopletId();
+                            Map attributes = new HashMap();
+                            Iterator i = cid.getAttributes().entrySet().iterator();
+                            while ( i.hasNext() ) {
+                                Map.Entry entry = (Map.Entry)i.next();
+                                attributes.put(entry.getKey(), entry.getValue());
+                            }
+                            i = cid.getCopletData().getAttributes().entrySet().iterator();
+                            while ( i.hasNext() ) {
+                                Map.Entry entry = (Map.Entry)i.next();
+                                attributes.put(entry.getKey(), entry.getValue());
+                            }
+                            ci.setAttribute("coplet-attributes", attributes);
+                        } catch (ServiceException se) {
+                            this.getLogger().warn("Unable to lookup portal service.", se);
+                        } finally {
+                            this.manager.release(service);
+                        }
+                        }
+                        source = resolver.resolveURI(url);
+                        ci.setContent(IOUtil.toByteArray(source.getInputStream()));
+                    } catch (IOException se) {
+                        this.getLogger().warn("Unable to get content for " + url, se);
+                    } catch (ServiceException se) {
+                        this.getLogger().warn("Unable to get source resolver.", se);
+                    } finally {
+                        if ( source != null ) {
+                            resolver.release(source);
+                        }
+                        this.manager.release(resolver);
+                    }
+                } else if ( ci.getURL() == null ) {
+                    // copy coplet attributes
+                    PortalService service = null;
+                    try {
+                        service = (PortalService) this.manager.lookup(PortalService.ROLE);
+                        CopletInstanceData cid = service.getComponentManager().getProfileManager().getCopletInstanceData(ci.getCopletId());
+                        Map attributes = new HashMap();
+                        Iterator i = cid.getAttributes().entrySet().iterator();
+                        while ( i.hasNext() ) {
+                            Map.Entry entry = (Map.Entry)i.next();
+                            attributes.put(entry.getKey(), entry.getValue());
+                        }
+                        i = cid.getCopletData().getAttributes().entrySet().iterator();
+                        while ( i.hasNext() ) {
+                            Map.Entry entry = (Map.Entry)i.next();
+                            attributes.put(entry.getKey(), entry.getValue());
+                        }
+                        ci.setAttribute("coplet-attributes", attributes);
+                    } catch (ServiceException se) {
+                        this.getLogger().warn("Unable to lookup portal service.", se);
+                    } finally {
+                        this.manager.release(service);
+                    }
+                }
+            store.addItem(ci);
+        } else { 
+            store.addItem(item);
+        }
+        this.saveContentStore(store);
+    }
+
+    /**
+     * Save the content store if it is a briefcase or a folder
+     */
+    protected void saveContentStore(ContentStore store) {
+        if ( store instanceof Briefcase ) {
+            this.saveContentStore(BRIEFCASE_KEY, store);
+        } else if ( store instanceof Folder ) {
+            this.saveContentStore(FOLDER_KEY, store);
+        }
+    }
+
+    /** 
+     * Load the content store for a single user
+     * @param type The type of the content store (briefcase or folder)
+     * @return The content store or null
+     */
+    protected ContentStore loadContentStore(String type, String userId) {
+        if ( this.directory != null ) {
+            final String suffix;
+            if ( FOLDER_KEY.equals(type) ) {
+                suffix = ".folder";
+            } else {
+                suffix = ".briefcase";
+            }
+            File file = new File(this.directory, userId + suffix);
+            if ( file.exists() ) {
+                try {
+                    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
+                    ContentStore store = (ContentStore)ois.readObject();
+                    ois.close();
+                    return store;
+                } catch (Exception ignore) {
+                    // ignore this
+                }
+            }
+        }
+        return null;
+    }
+    
+    /** 
+     * Load a content store
+     * @param type The type of the content store (briefcase or folder)
+     */
+    protected ContentStore loadContentStore(String type) {
+        ContentStore store = null;
+        String user = this.getUser();
+        if ( user != null ) {
+            store = this.loadContentStore(type, user);
+        }
+        if ( store == null && user != null ) {
+            try {
+                final String clazzName;
+                if ( BRIEFCASE_KEY.equals(type) ) {
+                    clazzName = this.briefcaseClassName;
+                } else {
+                    clazzName = this.folderClassName;
+                }
+                
+                final Class clazz = ClassUtils.loadClass(clazzName);
+                final Constructor constructor = clazz.getConstructor(new Class[] {String.class});
+                
+                store = (ContentStore)constructor.newInstance(new Object[] {user});
+            } catch (Exception ignore) {
+                if ( BRIEFCASE_KEY.equals(type) ) {
+                    store = new Briefcase(user);
+                } else {
+                    store = new Folder(user);
+                }
+            }
+        }
+        return store;
+    }
+    
+    /** 
+     * Delete the content store for a user
+     */
+    protected void deleteContentStore(String type, String userId) {
+        final String suffix;
+        if ( FOLDER_KEY.equals(type) ) {
+            suffix = ".folder";
+        } else {
+            suffix = ".briefcase";
+        }
+        if ( this.directory != null ) {
+            File file = new File(this.directory, userId+suffix);
+            if ( file.exists() ) {
+                file.delete();
+            }
+        }
+    }
+
+    /** 
+     * Save the content store for a single user
+     */
+    protected void saveContentStore(String type, ContentStore store) {
+        final String userId = store.getId();
+        final String suffix;
+        if ( FOLDER_KEY.equals(type) ) {
+            suffix = ".folder";
+        } else {
+            suffix = ".briefcase";
+        }
+        
+        if ( this.directory != null ) {
+            File file = new File(this.directory, userId+suffix);
+            try {
+                if ( !file.exists() ) {
+                    file.createNewFile();
+                    file = new File(this.directory, userId+suffix);
+                }
+                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
+                oos.writeObject(store);
+                oos.close();
+            } catch (Exception ignore) {
+                // ignore this
+            }
+        }
+    }
+    
+    /**
+     * Get briefcases of all users
+     */
+    protected List loadBriefcases() {
+        if ( this.directory != null ) {
+            File directory = new File(this.directory);
+            if ( directory.exists()) {
+                List briefcases = new ArrayList();
+                File[] files = directory.listFiles();
+                for(int i=0; i<files.length;i++) {
+                    String user = files[i].getName();
+                    int pos = user.indexOf(".briefcase");
+                    if ( pos != -1 ) {
+                        user = user.substring(0, pos);
+                        ContentStore store = this.loadContentStore(BRIEFCASE_KEY, user);
+                        if ( store != null ) {
+                            ContentStoreDescription bd = new ContentStoreDescription();
+                            bd.id = user;
+                            bd.size = store.contentSize();
+                            briefcases.add(bd);
+                        }
+                    }
+                }
+                return briefcases;
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBasket()
+     */
+    public Basket getBasket() {
+        Session session = ContextHelper.getRequest(this.context).getSession();
+        Basket basket = (Basket) session.getAttribute(BASKET_KEY);
+        if ( basket == null ) {
+            final String user = this.getUser();
+            try {
+                final Class clazz = ClassUtils.loadClass(this.basketClassName);
+                final Constructor constructor = clazz.getConstructor(new Class[] {String.class});
+                
+                basket = (Basket)constructor.newInstance(new Object[] {user});
+            } catch (Exception ignore) {
+                basket = new Basket(user);
+            }
+            session.setAttribute(BASKET_KEY, basket);
+        }
+        return basket;
+    }
+   
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBriefcase()
+     */
+    public Briefcase getBriefcase() {
+        Session session = ContextHelper.getRequest(this.context).getSession();
+        Briefcase briefcase = (Briefcase) session.getAttribute(BRIEFCASE_KEY);
+        if ( briefcase == null ) {
+            briefcase = (Briefcase)this.loadContentStore(BRIEFCASE_KEY);
+            session.setAttribute(BRIEFCASE_KEY, briefcase);
+        }
+        return briefcase;
+    }
+    
+    public Folder getFolder() {
+        Session session = ContextHelper.getRequest(this.context).getSession();
+        Folder folder = (Folder) session.getAttribute(FOLDER_KEY);
+        if ( folder == null ) {
+            folder = (Folder)this.loadContentStore(FOLDER_KEY);
+            session.setAttribute(FOLDER_KEY, folder);
+        }
+        return folder;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBriefcaseDescriptions()
+     */
+    public List getBriefcaseDescriptions() {
+        Session session = ContextHelper.getRequest(this.context).getSession();
+        List briefcases = (List)session.getAttribute(ALL_BRIEFCASES_KEY);
+        if ( briefcases == null ) {
+            briefcases = this.loadBriefcases();
+            if (briefcases == null) {
+                briefcases = new ArrayList();
+            }
+            session.setAttribute(ALL_BRIEFCASES_KEY, briefcases);
+        }
+        return briefcases;
+    }    
+    
+    /** 
+     * Get the current user
+     */
+    protected String getUser() {
+        PortalService service = null;
+        try {
+            service = (PortalService)this.manager.lookup(PortalService.ROLE);
+            return service.getComponentManager().getProfileManager().getUser().getUserName();
+        } catch (ServiceException ignore) {
+            // ignore this
+        } finally {
+            this.manager.release(service);
+        }
+        return null;
+        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBasketActions()
+     */
+    public List getBasketActions() {
+        return this.basketActions;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBriefcaseActions()
+     */
+    public List getBriefcaseActions() {
+        return this.briefcaseActions;
+        }
+        
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#addBatch(org.apache.cocoon.portal.coplets.basket.ContentItem, int, org.apache.cocoon.portal.coplets.basket.BasketManager.ActionInfo)
+     */
+    public void addBatch(ContentItem item, 
+                         int frequencyInDays,
+                         ActionInfo action) {
+        final String name = action.name + "_" + item;
+        
+        final BatchInfo info = new BatchInfo();
+        info.item = item;
+        info.frequencyInSeconds = frequencyInDays * 60 * 60 * 24;
+        info.action = action;
+        if ( frequencyInDays > 0 ) {
+            synchronized (this.batches) {
+                BatchInfo old = this.searchBatchInfo(item, action);
+                if ( old != null ) {
+                    this.batches.remove(old);
+                    this.scheduler.removeJob(name);
+                }
+                this.batches.add(info);
+            }
+        }
+        final Job job = new Job(action.url, item);
+        
+        try {
+            if ( frequencyInDays > 0) {
+                this.scheduler.addPeriodicJob(name, job, info.frequencyInSeconds, false, null, null);
+            } else {
+                this.scheduler.fireJob(job);
+            }
+                
+        } catch (Exception ignore) {
+            this.getLogger().warn("Exception during adding of new batch.", ignore);
+        }
+    }
+   
+    protected BatchInfo searchBatchInfo(ContentItem item, ActionInfo info) {
+        final Iterator i = this.batches.iterator();
+        while (i.hasNext()) {
+            final BatchInfo current = (BatchInfo)i.next();
+            if ( current.item.equals(item) ) {
+                if ( current.action.name.equals(info.name) ) {
+                    return current;
+                }
+            }
+        }
+        return null;
+    }
+    
+    protected static final class BatchInfo {
+        public ContentItem item;
+        public int frequencyInSeconds;
+        public ActionInfo action;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBasketAction(java.lang.String)
+     */
+    public ActionInfo getBasketAction(String name) {
+        final Iterator i = this.basketActions.iterator();
+        while ( i.hasNext() ) {
+            final ActionInfo current = (ActionInfo)i.next();
+            if ( current.name.equals(name) ) {
+                return current;
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#getBriefcaseAction(java.lang.String)
+     */
+    public ActionInfo getBriefcaseAction(String name) {
+        final Iterator i = this.briefcaseActions.iterator();
+        while ( i.hasNext() ) {
+            final ActionInfo current = (ActionInfo)i.next();
+            if ( current.name.equals(name) ) {
+                return current;
+            }
+        }
+        return null;
+    }
+    
+    public static final class Job extends ServiceableCronJob implements CronJob {
+        
+        protected final String url;
+        
+        public Job(String url, ContentItem item) {
+            final StringBuffer buffer = new StringBuffer(url);
+            boolean hasParams = url.indexOf('?') != -1;
+            Iterator i = item.attributes.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry current = (Map.Entry)i.next();
+                final String key = current.getKey().toString();
+                if ( !"coplet-attributes".equals(key) ) {
+                    if ( hasParams ) {
+                        buffer.append('&');
+                    } else {
+                        buffer.append('?');
+                        hasParams = true;
+                    }
+                    buffer.append(key);
+                    buffer.append('=');
+                    buffer.append(current.getValue().toString());
+                }
+            }
+            // now add coplet attributes
+            Map copletAttributes = (Map)item.attributes.get("coplet-attributes");
+            if ( copletAttributes != null ) {
+                i = copletAttributes.entrySet().iterator();
+                while ( i.hasNext() ) {
+                    final Map.Entry current = (Map.Entry)i.next();
+                    final String key = current.getKey().toString();
+                    if ( hasParams ) {
+                        buffer.append('&');
+                    } else {
+                        buffer.append('?');
+                        hasParams = true;
+                    }
+                    buffer.append(key);
+                    buffer.append('=');
+                    buffer.append(current.getValue().toString());
+                }
+            }
+            this.url = buffer.toString();
+        }    
+    
+        /* (non-Javadoc)
+         * @see org.apache.cocoon.components.cron.CronJob#execute(java.lang.String)
+         */
+        public void execute(String jobname) {
+            SourceResolver resolver = null;
+            Source source = null;
+            try {
+                resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+                source = resolver.resolveURI(this.url);
+
+                InputStreamReader r = new InputStreamReader(source.getInputStream());
+                try {
+                    char[] b = new char[8192];
+
+                    while( r.read(b) > 0) {
+                        // nothing to do
+                    }
+
+                } finally {
+                    r.close();
+                }
+            } catch (Exception ignore) {
+                // we ignore all
+                this.getLogger().warn("Exception during execution of job " + jobname, ignore);
+            } finally {
+                if ( resolver != null ) {
+                    resolver.release(source);
+                    this.manager.release(resolver);
+                }
+            }
+        }
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.portal.coplets.basket.BasketManager#update(org.apache.cocoon.portal.coplets.basket.ContentStore)
+     */
+    public void update(ContentStore store) {
+        this.saveContentStore(store);
+    }
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketManagerImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.portal.PortalService;
+import org.apache.cocoon.portal.coplet.CopletInstanceData;
+import org.apache.cocoon.portal.coplets.basket.BasketManager.ActionInfo;
+import org.apache.cocoon.portal.coplets.basket.events.AddItemEvent;
+import org.apache.cocoon.portal.event.Event;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This transformer supports the basket and briefcase feature. It can generate links to
+ * add content into a content store.
+ *
+ * @version CVS $Id$
+ */
+public class BasketTransformer
+    extends AbstractBasketTransformer {
+
+    /** Element to add a link */
+    protected static final String ADD_ITEM_ELEMENT = "add-item";
+
+    /** Element to show all actions */
+    protected static final String SHOW_ACTIONS_ELEMENT = "show-actions";
+
+    /** The default store: briefcase or basket */
+    protected String defaultStoreName = "basket";
+
+    /** The default link element name */
+    protected String defaultLinkElement = "a";
+
+    /** The default namespace for the link element */
+    protected String defaultLinkElementNS = "";
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        super.configure(configuration);
+        this.defaultStoreName = configuration.getChild("default-store").getValue(this.defaultStoreName);
+        this.defaultLinkElement = configuration.getChild("default-link-element").getValue(this.defaultLinkElement);
+        this.defaultLinkElementNS = configuration.getChild("default-link-element-ns").getValue(this.defaultLinkElementNS);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endTransformingElement(String uri, String name, String raw)
+    throws ProcessingException, IOException, SAXException {
+        if ( ADD_ITEM_ELEMENT.equals(name) ) {
+            final String linkElementName = this.parameters.getParameter("link-element", this.defaultLinkElement);
+            final String linkElementNS = this.parameters.getParameter("link-element-ns", this.defaultLinkElementNS);
+            XMLUtils.endElement(this.contentHandler, linkElementNS, linkElementName);
+        } else if ( SHOW_ACTIONS_ELEMENT.equals(name) ) {
+            // nothing to do here
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startTransformingElement(String uri, String name,
+                                         String raw, Attributes attr)
+    throws ProcessingException, IOException, SAXException {
+        if ( ADD_ITEM_ELEMENT.equals(name) ) {
+            PortalService service = null;
+            try {
+                service = (PortalService)this.manager.lookup(PortalService.ROLE);
+
+                // do we want to add content or a link?
+            boolean addContent = false;
+                final String value = attr.getValue("content");
+            if ( value != null ) {
+                addContent = new Boolean(value).booleanValue();
+            }
+                
+                // do we want to add a url or a coplet?
+                final ContentItem ci;
+                final String href = attr.getValue("href");            
+                if ( href != null ) {
+                    ci = new ContentItem(href, addContent);
+                } else {
+                    final String copletId = attr.getValue("coplet");
+                    final CopletInstanceData cid = service.getComponentManager().getProfileManager().getCopletInstanceData(copletId);                    
+                    ci = new ContentItem(cid, addContent);
+            }
+
+                // do we want to add the content to the basket or to the briefcase
+                final ContentStore store;
+                final String storeName = (attr.getValue("store") == null ? this.defaultStoreName : attr.getValue("store"));
+                if ("basket".equalsIgnoreCase(storeName) )     {
+                    store = this.basketManager.getBasket();
+                } else {
+                    store = this.basketManager.getBriefcase();
+                }
+
+                final Event e = new AddItemEvent(store, ci);
+                final AttributesImpl ai = new AttributesImpl();
+                String newLink = service.getComponentManager().getLinkService().getLinkURI(e);
+                // check for bockmark
+                final String bookmark = attr.getValue("bookmark");
+                if ( bookmark != null && bookmark.length() > 0) {
+                    int pos = newLink.indexOf('?') + 1;
+                    final char separator;
+                    if ( bookmark.indexOf('?') == -1 ) {
+                        separator = '?';
+                    } else {
+                        separator = '&';
+                    }
+                    newLink = bookmark + separator + newLink.substring(pos);
+                }
+                ai.addCDATAAttribute("href", newLink);
+                
+                final String linkElementName = this.parameters.getParameter("link-element", this.defaultLinkElement);
+                final String linkElementNS = this.parameters.getParameter("link-element-ns", this.defaultLinkElementNS);
+                XMLUtils.startElement(this.contentHandler, linkElementNS, linkElementName, ai);
+            } catch (ServiceException se) {
+                throw new SAXException("Unable to lookup portal service.", se);
+            } finally {
+                this.manager.release(service);
+            }
+        } else if ( SHOW_ACTIONS_ELEMENT.equals(name) ) {
+            // basket or briefcase
+            final List actions;
+            final String storeName = (attr.getValue("store") == null ? this.defaultStoreName : attr.getValue("store"));
+            if ("basket".equalsIgnoreCase(storeName) )     {
+                actions = this.basketManager.getBasketActions();
+            } else {
+                actions = this.basketManager.getBriefcaseActions();
+                }
+            final String checkedAction = attr.getValue("checked");
+            final Iterator i = actions.iterator();
+            AttributesImpl a = new AttributesImpl();
+            while ( i.hasNext() ) {
+                final BasketManager.ActionInfo current = (ActionInfo) i.next();
+                a.addCDATAAttribute("name", current.name);
+                if ( current.name.equals(checkedAction) ) {
+                    a.addCDATAAttribute("checked", "true");
+            }
+                XMLUtils.createElement(this.xmlConsumer, "action", a);
+                a.clear();
+            }
+        }
+    }
+
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/BasketTransformer.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+/**
+ * This is a per user basket that is persistent between sessions
+ * Make a subclass to add your specific functionality
+ *
+ * @version CVS $Id$
+ */
+public class Briefcase extends ContentStore {
+    
+    public Briefcase(String id) {
+        super(id);
+    }
+}
\ No newline at end of file

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Briefcase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.Serializable;
+
+import org.apache.cocoon.portal.coplet.CopletInstanceData;
+
+
+/**
+ * This is an item that contains a link or a content.
+ * The item can either reference a coplet or an URL.
+ *
+ * @version CVS $Id$
+ */
+public class ContentItem extends AbstractItem implements Serializable {
+    
+    /** The id of the referenced coplet */
+    protected String copletId;
+    /** Do we store the content or just the link? */
+    protected boolean storesContent;
+    /** The referenced url */
+    protected String url;
+    /** The cached string rep */
+    protected String stringRep;
+    /** The content */
+    protected byte[] content;
+    
+    /**
+     * Create a new item referencing a coplet instance data
+     * @param cid     The coplet
+     * @param content Do we store the content (false: a link)
+     */
+    public ContentItem(CopletInstanceData cid, boolean content) {
+        this.copletId = cid.getId();
+        this.storesContent = content;
+    }
+
+    /**
+     * Create a new item referencing to a url
+     * @param url     The url
+     * @param content Do we store the content (false: a link)
+     */
+    public ContentItem(String url, boolean content) {
+        this.url = url;
+        this.storesContent = content;
+    }
+    
+    /**
+     * Return the url of null for a coplet
+     */
+    public String getURL() {
+        return this.url;
+    }
+    
+    /**
+     * Return the referenced coplet or null for a url
+     */
+    public String getCopletId() {
+        return this.copletId;
+    }
+    
+    /**
+     * Do we store the content? (or just the link)
+     */
+    public boolean isContent() {
+        return this.storesContent;
+    }
+    
+    /**
+     * Set the content
+     */
+    public void setContent(byte[] c) {
+        this.storesContent = true;
+        this.content = c;
+    }
+    
+    /**
+     * Get the content or null
+     */
+    public byte[] getContent() {
+        return this.content;
+    }
+    
+    /**
+     * Return the size if content is stored
+     * Otherwise -1 is returned
+     */
+    public int size() {
+        if ( this.content != null ) {
+            return this.content.length;
+        }
+        return -1;
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        if ( this.stringRep == null ) {
+            if ( this.copletId != null ) {
+                this.stringRep = "Coplet:" + this.copletId + "(" + this.storesContent + ")";
+            } else {
+                this.stringRep = "URL:" + this.url + "(" + this.storesContent + ")";
+            }
+        }
+        return this.stringRep;
+    }
+    
+    /**
+     * Compare one item with another
+     */
+    public boolean equalsItem(ContentItem ci) {
+        if ( ci != null && ci.storesContent == this.storesContent ) {
+            if ( ci.url != null && ci.url.equals(this.url)) {
+                return true;
+            }
+            if ( ci.copletId != null 
+                 && this.copletId != null 
+                 && ci.copletId.equals(this.copletId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public void setTitle(String title) {
+        this.stringRep = title;
+    }
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentItem.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * This is a per user store that can contain any object. 
+ * Make a subclass to add your specific functionality.
+ *
+ * @version CVS $Id$
+ */
+public abstract class ContentStore implements Serializable {
+    
+    /** The ordered list of items */
+    protected final List items = new ArrayList();
+    
+    /** The id */
+    protected final String id;
+    
+    /**
+     * The constructor
+     */
+    public ContentStore(String id) {
+        this.id = id;
+    }
+    
+    /**
+     * @return Returns the id.
+     */
+    public String getId() {
+        return this.id;
+    }
+    
+    /**
+     * Get an item at the index
+     */
+    public Object getItem(int index) {
+        return this.items.get(index);
+    }
+    
+    /**
+     * Add an item
+     */
+    public void addItem(Object item) {
+        this.items.add(item);
+    }
+    
+    /**
+     * Get the iterator
+     */
+    public Iterator getIterator() {
+        return this.items.iterator();
+    }
+    
+    /**
+     * Remove an item
+     */
+    public void removeItem(Object item) {
+        this.items.remove(item);
+    }
+    
+    /**
+     * Number of items in the basket
+     */
+    public int size() {
+        return this.items.size();
+    }
+
+    /**
+     * Calculate the size of a basket
+     */
+    public int contentSize() {
+        int size = 0;
+        Iterator i = this.items.iterator();
+        while (i.hasNext()) {
+            Object item = i.next();
+            if ( item instanceof ContentItem ) {
+                int v = ((ContentItem)item).size();
+                if ( v != -1 ) {
+                    size += v;
+                }
+            }
+        }
+        return size;
+    }
+    
+    /**
+     * Get an item with the id
+     */
+    public Object getItem(long id) {
+        Iterator i = this.items.iterator();
+        while (i.hasNext()) {
+            Object item = i.next();
+            if ( item instanceof AbstractItem ) {
+                if (((AbstractItem)item).getId() == id ) {
+                    return item;
+                }
+            }
+        }
+        return null;        
+    }
+}
+

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStore.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+/**
+ * This class describes a {@link ContentStore}.
+ *
+ * @version CVS $Id$
+ */
+public class ContentStoreDescription {
+
+    /** The id */
+    public String id;
+    /** The size of the basket */
+    public int    size;
+
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/ContentStoreDescription.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+/**
+ * This is a per user basket that is persistent between sessions
+ * Make a subclass to add your specific functionality
+ *
+ * @version CVS $Id$
+ */
+public class Folder extends ContentStore {
+
+    public Folder(String id) {
+        super(id);
+    }
+
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/Folder.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java?rev=265679&view=auto
==============================================================================
--- cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java (added)
+++ cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java Thu Sep  1 02:08:10 2005
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2004-2005 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.cocoon.portal.coplets.basket;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.wrapper.RequestParameters;
+import org.apache.cocoon.portal.PortalService;
+import org.apache.cocoon.portal.coplets.basket.events.UploadItemEvent;
+import org.apache.cocoon.portal.event.Event;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This transformer supports the basket feature. It can generate links to
+ * add content and to upload files into the basket.
+ *
+ * @version $Id$
+ */
+public class FolderTransformer extends AbstractBasketTransformer {
+
+    /** Element to upload an item */
+    protected static final String UPLOAD_ITEM_ELEMENT = "upload-item";
+
+    /** Element for the upload form */
+    protected static final String UPLOAD_FORM_ELEMENT = "upload-form";
+
+    /** Upload element list */
+    protected List uploadElements = new ArrayList();
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        this.uploadElements.clear();
+        super.recycle();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endTransformingElement(String uri, String name, String raw)
+    throws ProcessingException, IOException, SAXException {
+        if ( UPLOAD_ITEM_ELEMENT.equals(name) ) {
+            this.endElement("", "input", "input");
+        } else if ( UPLOAD_FORM_ELEMENT.equals(name) ) {
+            this.endElement("", "form", "form");
+            this.uploadElements = new ArrayList();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startTransformingElement(String uri, String name,
+                                         String raw, Attributes attr)
+    throws ProcessingException, IOException, SAXException {
+        if ( UPLOAD_ITEM_ELEMENT.equals(name) ) {
+            this.uploadElements.add(attr.getValue("name"));
+            this.startElement("", "input", "input", attr);
+        } else if ( UPLOAD_FORM_ELEMENT.equals(name) ) {
+            AttributesImpl ai = new AttributesImpl(attr);
+            PortalService service = null;
+            String parameters;
+            try {
+                service = (PortalService)this.manager.lookup(PortalService.ROLE);
+                Event e = new UploadItemEvent(this.basketManager.getFolder(), this.uploadElements);
+                parameters = service.getComponentManager().getLinkService().getLinkURI(e);
+                int pos = parameters.indexOf('?');
+                ai.addCDATAAttribute("action", parameters.substring(0, pos));
+                parameters = parameters.substring(pos+1);
+            } catch (ServiceException se) {
+                throw new SAXException("Unable to lookup portal service.", se);
+            } finally {
+                this.manager.release(service);
+            }
+            this.startElement("", "form", "form", ai);
+            if ( parameters != null && parameters.length() > 0 ) {
+                // create hidden input fields
+                RequestParameters pars = new RequestParameters(parameters);
+                Enumeration enumPars = pars.getParameterNames();
+                while ( enumPars.hasMoreElements() ) {
+                    String pName = (String)enumPars.nextElement();
+                    String pValue = pars.getParameter(pName);
+                    AttributesImpl hiddenAttrs = new AttributesImpl();
+                    hiddenAttrs.addCDATAAttribute("type", "hidden");
+                    hiddenAttrs.addCDATAAttribute("name", pName);
+                    hiddenAttrs.addCDATAAttribute("value", pValue);
+                    this.startElement("", "input", "input", hiddenAttrs);
+                    this.endElement("", "input", "input");
+                }
+            }
+        }
+    }
+
+}

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal-sample/trunk/java/org/apache/cocoon/portal/coplets/basket/FolderTransformer.java
------------------------------------------------------------------------------
    svn:keywords = Id