| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.framework.activity.Disposable; |
| import org.apache.avalon.framework.activity.Initializable; |
| import org.apache.avalon.framework.component.Component; |
| 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.commons.io.IOUtils; |
| 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, Component { |
| |
| /** 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 = IOUtils.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 |
| */ |
| 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", IOUtils.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(IOUtils.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); |
| } |
| } |