Package de.innovationgate.wgpublisher.webtml.utils

Source Code of de.innovationgate.wgpublisher.webtml.utils.TMLPortlet

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.webtml.utils;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpSession;

import org.apache.commons.collections.map.LinkedMap;

import de.innovationgate.utils.NullPlaceHolder;
import de.innovationgate.utils.TransientObjectWrapper;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGIllegalArgumentException;
import de.innovationgate.webgate.api.WGIllegalStateException;
import de.innovationgate.webgate.api.WGPortlet;
import de.innovationgate.webgate.api.WGPortletRegistry;

import de.innovationgate.wga.common.CodeCompletion;
import de.innovationgate.wgpublisher.WGACore;
import de.innovationgate.wgpublisher.webtml.Base;
import de.innovationgate.wgpublisher.webtml.BaseTagStatus;
import de.innovationgate.wgpublisher.webtml.Root;

@CodeCompletion(methodMode=CodeCompletion.MODE_INCLUDE)
public class TMLPortlet implements TMLObject {
   
    /**
     * Collects all session based settings belonging to a portlet
     */
    public static class SessionContext implements Serializable {
       
        private String mode = DEFAULT_PORTLET_MODE;
        private transient long lastProcessedEventIndex = Long.MIN_VALUE;
       
        private String contextPath = null;
       
        public long getLastProcessedEventIndex() {
            return lastProcessedEventIndex;
        }
        public void setLastProcessedEventIndex(long lastProcessedSsEventIndex) {
            this.lastProcessedEventIndex = lastProcessedSsEventIndex;
        }
        public String getMode() {
            return mode;
        }
        public void setMode(String mode) {
            this.mode = mode;
        }
    public String getContextPath() {
      return contextPath;
    }
    public void setContextPath(String contextPath) {
      if (contextPath != null && contextPath.trim().equalsIgnoreCase("none")) {
        this.contextPath = null;
      } else {
        this.contextPath = contextPath;
      }
    }
   
    private Object readResolve() throws ObjectStreamException {
        lastProcessedEventIndex = Long.MIN_VALUE;
        return this;
    }
       
    }
   
   

    public static final String DEFAULT_PORTLET_MODE = "view";
    public static final String PORTLETNAME_ITEM_PREFIX = "$pname_";
    public static final Pattern PORTLETNAME_PATTERN = Pattern.compile("[a-zA-Z0-9_\\.\\-\\:]+");
    public static final String PORTLET_EVENT_REQUEST_ATTR_PREFIX = "de.innovationgate.wgpublisher.webtml.utils.TMLPortlet.Events_";
    private static final int EVENTQUEUE_MAX_SIZE = 1000;
    public static final String PORTLETCONTEXT_NONE = "none";

  private TMLUserProfile profile = null;

  private WGPortlet reg = null;
  public HashMap hmPortletModes = new HashMap();
  public BaseTagStatus tag = null;
  public List lstKeysToDelete = Collections.synchronizedList(new ArrayList());

  public TMLPortlet(BaseTagStatus tag, TMLUserProfile profile, WGPortlet portlet) throws WGAPIException {
    this.tag = tag;
    this.profile = profile;
    reg = portlet;
  }

  /**
   * @see de.innovationgate.wgpublisher.webtml.utils.TMLObject#getAPIObject()
   */
  public WGDocument getapiobject() {
    return null;
  }

  @CodeCompletion
  public Object item(String name) throws WGAPIException {
      WGPortletRegistry registry = this.profile.getprofile().getPortletRegistry();
      if (registry.hasItem(reg, name)) {
          return TMLContext.flattenList(registry.getItemValue(reg, name));
      }
      else {
          return profile.getprofile().getDatabase().getNoItemBehaviour().getForTMLItem();
      }
     
       
  }

  @CodeCompletion
  public List itemlist(String name) throws WGAPIException {
      WGPortletRegistry registry = this.profile.getprofile().getPortletRegistry();
      if (registry.hasItem(reg, name)) {
          return TMLContext.toList(registry.getItemValue(reg, name));
      }
      else {
          return profile.getprofile().getDatabase().getNoItemBehaviour().getForTMLItemList();
      }
  }

  @CodeCompletion
    public boolean hasitem(String name) throws WGAPIException {
        return this.profile.getprofile().getPortletRegistry().hasItem(reg, name);
    }
   
  public Object meta(String name) throws WGAPIException {
    return this.profile.meta(name);
  }

  public List metalist(String name) throws WGAPIException {
    return this.profile.metalist(name);
  }

  @CodeCompletion
  public boolean save() throws WGAPIException {
    return this.profile.save();
  }

  @CodeCompletion
  public boolean setitem(String name, Object value) throws WGAPIException {
      this.profile.getprofile().getPortletRegistry().setItemValue(reg, name, value);
      return true;
  }
   
  @CodeCompletion
    public void setvar(String name, Object value) throws WGAPIException {
        if (!isroot()) {
            tag.tmlContext.setvar(getVarPrefix() + name, value);
        }
        else {
            throw new WGIllegalStateException("Portlet var not allowed on root scope");
        }   
    }
   
    @CodeCompletion
    public Object getvar(String name) throws WGAPIException {
        if (!isroot()) {
            return tag.tmlContext.getvar(getVarPrefix() + name);
        }
        else {
            return null;
        }
    }

    @CodeCompletion
    public void removevar(String name) throws WGAPIException {
        if (!isroot()) {
            tag.tmlContext.removevar(getVarPrefix() + name);
        }
    }
   
    @CodeCompletion
    public void setsessionvar(String name, Object value) throws WGAPIException {
      setsessionvar(name, value, true);
    }
   
    @CodeCompletion
    public Object getsessionvar(String name) throws WGAPIException {
      if (!isroot()) {
            return tag.tmlContext.getsessionvar(getVarPrefix() + name);
        } else {
          return null;
        }
    }
   
    @CodeCompletion
    public void setsessionvar(String name, Object value, boolean allowSerialization) throws WGAPIException {
        if (!isroot()) {
            tag.tmlContext.setSessionVar(getVarPrefix() + name, value, allowSerialization, true);
        }
        else {
            throw new WGIllegalStateException("Portlet session vars not allowed on root portlet");
        }
    }
   
    @CodeCompletion
    public void removesessionvar(String name) throws WGAPIException {
        if (!isroot()) {
            tag.tmlContext.removesessionvar(getVarPrefix() + name);
        }
    }
   
   
    @CodeCompletion
    public void removeitem(String name) throws WGAPIException {
        profile.getprofile().getPortletRegistry().removeItem(reg, name);
    }


  public TMLPortlet getportlet(String key) throws WGAPIException {
   
    WGPortlet portlet  = getPortletRegistration(key);
     
    if (portlet != null) {
      return new TMLPortlet(tag, profile, portlet);
    }
    else {
      return null;
    }
   
  }

    public WGPortlet getPortletRegistration(String key) throws WGAPIException {
        return profile.getprofile().getPortletRegistry().getPortlet(tag.tmlContext.getmaincontext().db().getDbReference(), key);
    }

    @CodeCompletion
  public TMLPortlet getparentportlet() throws WGAPIException {
      if (reg.getParentPortletKey() != null) {
          return getportlet(reg.getParentPortletKey());
      }
      else {
          return this;
      }
  }
 
  public List getchildrenkeys() throws WGAPIException {
      Iterator<WGPortlet> childRegs = profile.getprofile().getPortletRegistry().getChildPortlets(reg).iterator();
            List childKeys = new ArrayList();
            while (childRegs.hasNext()) {
                WGPortlet portlet = childRegs.next();
                childKeys.add(portlet.getKey());
            }
            return childKeys;
  }
   
    public List getdescendantkeys() throws WGAPIException {
        Iterator childRegs = getChildRegistrations(reg, true).iterator();
        List childKeys = new ArrayList();
        while (childRegs.hasNext()) {
            WGPortlet reg = (WGPortlet) childRegs.next();
            childKeys.add(reg.getKey());
        }
        return childKeys;
    }
   
    @CodeCompletion
    public List getchildrennames() throws WGAPIException {
        Iterator<WGPortlet> childRegs = profile.getprofile().getPortletRegistry().getChildPortlets(reg).iterator();
        List childKeys = new ArrayList();
        while (childRegs.hasNext()) {
            WGPortlet reg = (WGPortlet) childRegs.next();
            childKeys.add(reg.getName());
        }
        return childKeys;
}

    public List getdescendantnames() throws WGAPIException {
        Iterator childRegs = getChildRegistrations(reg, true).iterator();
        List childKeys = new ArrayList();
        while (childRegs.hasNext()) {
            WGPortlet reg = (WGPortlet) childRegs.next();
            childKeys.add(reg.getName());
        }
        return childKeys;
    }


  // register portlet and update Hashmap
  public String registerportlet(String tmlDb, String tmlCode, String title) throws WGAPIException {

    WGPortlet newPortlet = profile.getprofile().getPortletRegistry().createPortlet(tag.tmlContext.getmaincontext().db().getDbReference(), reg);
    newPortlet.setDesignDb(tmlDb);
    newPortlet.setDesign(tmlCode);
    newPortlet.setName(title);
    profile.getprofile().getPortletRegistry().insertPortlet(newPortlet);
   

    TMLPortlet newTMLPortlet = new TMLPortlet(tag, profile, newPortlet);
   
      // Fetch portlet session context (so the following init event will not be overridden)
    newTMLPortlet.getSessionContext();
       
        // Add portlet init event
        PortletEvent event = new PortletEvent("init");
        event.setSource(newPortlet.getKey());
        event.setSourceName(title);
        event.setTargetPortletKey(newPortlet.getKey());
        addEventToQueue(event, tag.tmlContext.gethttpsession());       
       
    return newPortlet.getKey();
  }

  public String registerportlet(String tmlCode, String title) throws WGAPIException {
      return registerportlet(null, tmlCode, title);
  }

      // unregister portlet and update Hashmap
    public boolean unregisterportlet(String portletKey) throws WGAPIException {

    TMLPortlet portlet = getportlet(portletKey);

    if (portlet == null) {
            throw new WGIllegalArgumentException("Unable to unregister portlet with key '" + portletKey + "' - no portlet with this key registered.");
        }
     
    portlet.unregister();
        return true;
  }
   
    public void unregister() throws WGAPIException {
        this.profile.getprofile().getPortletRegistry().removePortlet(reg);
        cleanupPortletSession();
        this.profile.save(true);
    }

  private List<WGPortlet> getChildRegistrations(WGPortlet parent, boolean descendants) throws WGAPIException {

    List<WGPortlet> childRegs = new ArrayList<WGPortlet>();

    Iterator<WGPortlet> iter = profile.getprofile().getPortletRegistry().getChildPortlets(parent).iterator();

    while (iter.hasNext()) {
      WGPortlet child = (WGPortlet) iter.next();
      childRegs.add(child);
            if (descendants) {
                childRegs.addAll(getChildRegistrations(child, true));
            }
    }
    return childRegs;

  }


  @CodeCompletion
  public void cleanup() throws WGAPIException {
     
      this.profile.getprofile().getPortletRegistry().clearItems(reg);
        cleanupPortletSession();

  }

  @CodeCompletion
    public void cleanupPortletSession() {
        // Remove the session context
        String completeKey = getSessionContextKey();
        HttpSession session = tag.tmlContext.getEnvironment().getPageContext().getSession();
       
        synchronized (session) {
            Map contexts = getPortletSessionContexts(session);
            contexts.remove( completeKey );
        }
       
        // Remove portlet variables
        tag.tmlContext.removePortletVariables(this);
    }
 
  public void cleanup(String portletKey) throws WGAPIException {
     
      TMLPortlet portlet = getportlet(portletKey);
      if (portlet != null) {
          portlet.cleanup();
      }
      else {
          throw new WGIllegalArgumentException("Unable to cleanup portlet with key '" + portletKey + "' - no portlet with this key registered.");
  }
 
  }

  /**
   * Returns the title.
   * @return String
   */

  public String getportletkey() {
    return reg.getKey();
  }

  public String getparentkey() {
    return reg.getParentPortletKey();
  }

  @CodeCompletion
  public String gettml() {
    return reg.getDesign();
  }
 
  @CodeCompletion
  public String gettmldb() {
        return reg.getDesignDb();
    }
 

 
  public List getitemnames() throws WGAPIException {
      return this.profile.getprofile().getPortletRegistry().getItemNames(reg);
  }
 

  public String gettitle() {
    return reg.getName();
  }
   
  @CodeCompletion
    public String getname() {
        return reg.getName();
    }
  /**
   * Returns the mode.
   * @return String
   */
    @CodeCompletion
  public String getmode() {

        return getSessionContext().getMode();
   
  }


 
  public SessionContext getSessionContext() {
       
   
        String completeKey = getSessionContextKey();
        HttpSession session = tag.tmlContext.gethttpsession();
       
        synchronized (session) {
           
            // Get - conditionally create session context map
            Map contexts = getPortletSessionContexts(session);
       
            // Get - conditionally create individual session context
        SessionContext context = (SessionContext) contexts.get( completeKey );
            if (context == null) {
                context = new SessionContext();
               
                // Set event index to current last index, so events fired before creation of this context are not executed for it
                LinkedMap list = TMLPortlet.getFiredEventsQueue(session);
                if (!list.isEmpty()) {
                    PortletEvent event = (PortletEvent) list.get(list.lastKey());
                    context.setLastProcessedEventIndex(event.getIndex());
                }
                               
                contexts.put(completeKey, context);
            }
            return context;
        }
   
  }
   
    private String getSessionContextKey() {
        return profile.getprofile().getDatabase().getDbReference() + "/" + getportletkey();
    }

    private static Map getPortletSessionContexts(HttpSession session) {
       
        synchronized (session) {
            Map contexts = (Map) session.getAttribute(WGACore.SESSION_PORTLETMODES);
            if (contexts == null) {
                contexts = Collections.synchronizedMap(new HashMap());
                session.setAttribute(WGACore.SESSION_PORTLETMODES, contexts);
            }
            return contexts;
        }
    }
   
    /**
     * Queue that stores the last 1000 fired portlet events, so portlets can
     * react on them with serverside code.
     * @param session
     * @return
     */
    public static LinkedMap getFiredEventsQueue(HttpSession session) {
       
        synchronized (session) {
            TransientObjectWrapper<LinkedMap> eventWrapper = (TransientObjectWrapper<LinkedMap>) session.getAttribute(WGACore.SESSION_FIREDPORTLETEVENTS);
            if (eventWrapper == null || eventWrapper.get() == null) {
                eventWrapper = new TransientObjectWrapper<LinkedMap>();
                eventWrapper.set(new LinkedMap());
                session.setAttribute(WGACore.SESSION_FIREDPORTLETEVENTS, eventWrapper);
            }
            return eventWrapper.get();
        }
       
    }
   
    protected static void addEventToQueue(PortletEvent event, HttpSession session) {
       
        LinkedMap events = getFiredEventsQueue(session);
       
        synchronized (events) {
            event.retrieveIndex();
            events.put(new Long(event.getIndex()), event);
            while (events.size() > EVENTQUEUE_MAX_SIZE) {
                events.remove(events.firstKey());
            }
        }
       
       
    }

  /**
   * Sets the mode.
   * @param mode The mode to set
   */
    @CodeCompletion
  public void setmode(String mode) {
    getSessionContext().setMode(mode);
  }

  public void changeDesign(String tml) throws WGAPIException {
    reg.setDesign(tml);
    this.profile.save(true);
  }

  public String getDesign() {
    return reg.getDesign();
  }

  @CodeCompletion
    public void fireevent(PortletEvent event) {
        // store event in hashSet and request for rendering through include tag
        HashSet currentEvents = (HashSet) this.tag.tmlContext.getrequest().getAttribute(PORTLET_EVENT_REQUEST_ATTR_PREFIX + this.reg.getKey());
        if (currentEvents == null) {
            currentEvents = new HashSet();
            this.tag.tmlContext.getrequest().setAttribute(PORTLET_EVENT_REQUEST_ATTR_PREFIX + this.reg.getKey(), currentEvents);
        }
        // set source
        event.setSource(getportletkey());
        event.setSourceName(getname());
        currentEvents.add(event);
       
        // Add to event queue
        addEventToQueue(event, this.tag.tmlContext.gethttpsession());
    }
   
  @CodeCompletion
    public void fireevent(String eventname) {
      fireevent(tag.tmlContext.createevent(eventname));
    }
   
  @CodeCompletion
    public String registerportletforname(String name, String moduleDb, String module, boolean overwrite) throws WGAPIException {
       
        // Verify portlet name rules
        if (!PORTLETNAME_PATTERN.matcher(name).matches()) {
            throw new WGIllegalArgumentException("The portletname may only consist of characters A-Z, a-z, 0-9, _, ., - and :");
        }
       
        // Verify portlet name not already used
        TMLPortlet portlet = getportletforname(name);
        if (portlet != null) {
            if (overwrite) {
                unregisterportletforname(name);
            }
            else {
                throw new WGIllegalArgumentException("Portlet name '" + name + "' already registered.");
            }
        }
       
        String pkey = registerportlet(moduleDb, module, name);
        setitem(PORTLETNAME_ITEM_PREFIX + name, pkey);
        save();
        return pkey;
       
    }
 
  @CodeCompletion
    public String registerportletforname(String name, String module, boolean overwrite) throws WGAPIException {
        return registerportletforname(name, null, module, overwrite);
    }
   
  @CodeCompletion
    public String registerportletforname(String name, String module) throws WGAPIException {
        return registerportletforname(name, null, module, false);
    }
 
  @CodeCompletion
    public String registerportletforname(String name, String moduleDb, String module) throws WGAPIException {
        return registerportletforname(name, moduleDb, module, false);
    }
   

    @CodeCompletion
    public TMLPortlet getportletforname(String name) throws WGAPIException {
       
        if (!hasitem(PORTLETNAME_ITEM_PREFIX + name)) {
            return null;
        }
       
        String pkey = getPortletKeyForName(name);
        return getportlet(pkey);
       
    }

    public String getPortletKeyForName(String name) throws WGAPIException {
        String pkey = (String) item(PORTLETNAME_ITEM_PREFIX + name);
        return pkey;
    }
   
    @CodeCompletion
    public void unregisterportletforname(String name) throws WGAPIException {
       
        String key = getPortletKeyForName(name);
        if (key == null) {
            throw new WGIllegalArgumentException("No portlet of name '" + name + "' exists in the current portlet scope");
        }
        unregisterportlet(key);
        removeitem(PORTLETNAME_ITEM_PREFIX + name);
        save();
       
    }
   
    @CodeCompletion
    public void unregisterchildportlets() throws WGAPIException {
       
        Iterator keys = getchildrenkeys().iterator();
        while (keys.hasNext()) {
            String key = (String) keys.next();
            TMLPortlet child = getportlet(key);
            if (child != null) {
                unregisterportlet(child.getportletkey());
            }
        }
        save();
       
       
    }
    public void prepareEventProcessing(Base tag) {
       
       
        SessionContext sessionContext = getSessionContext();
        LinkedMap list = TMLPortlet.getFiredEventsQueue(tag.getPageContext().getSession());
       
        // Look if the event queue proceeded since the last processed event
        if (list.size() > 0) {
            PortletEvent lastEvent = (PortletEvent) list.get(list.lastKey());
            if (lastEvent != null) {
                if (lastEvent.getIndex() > sessionContext.getLastProcessedEventIndex()) {
                   
                    // Find the start index for processing new events
                    Long startIndex;
                    Long lastProcessedIndex = new Long(sessionContext.getLastProcessedEventIndex());
                    if (list.containsKey(lastProcessedIndex)) {
                        startIndex = (Long) list.nextKey(lastProcessedIndex);
                    }
                    else {
                        startIndex = (Long) list.firstKey();
                    }
                   
                    // Set start index as WebTML option
                    tag.getStatus().setOption(Base.OPTION_PORTLET_EVENT_STARTINDEX, new Long(sessionContext.getLastProcessedEventIndex()), null);
                   
                    // Update last processed event index to be the newest event's index
                    sessionContext.setLastProcessedEventIndex(lastEvent.getIndex());
                }
            }
        }
    }
   
   
   
    public boolean isroot() {
        return (reg.isRoot());
    }

       
    @CodeCompletion
    public TMLPortlet getroot() throws WGAPIException {
       
        TMLPortlet portlet = this;
        while (!portlet.isroot()) {
            portlet = portlet.getparentportlet();
        }
       
        return portlet;
       
    }
   
    public TMLPortlet parent() throws WGAPIException {
        return getparentportlet();
    }
   
    public TMLPortlet child(String name) throws WGAPIException {
        return getportletforname(name);
    }
   
    /**
     * returns the session based context used for this portlet
     * @return
     */
    public TMLContext getcontext() {
      if (tag == null) {
        return null;
      }
      if (getSessionContext().getContextPath() != null) {
        return tag.tmlContext.context(getSessionContext().getContextPath());
      } else {
        return null;
      }
    }
   
    /**
     * sets the session based context used for this portlet
     * @param context
     * @throws WGAPIException
     */
    public void setcontext(TMLContext context) throws WGAPIException {
      if (tag == null) {
        throw new WGIllegalStateException("Portlet context is not supported on none webtml environments.");
      } else if (! (tag instanceof Root.Status)) {
        throw new WGIllegalStateException("Portlet context cannot be set outside actions.");
      }
      if (context != null) {
        getSessionContext().setContextPath(context.getpath());
      } else {
        getSessionContext().setContextPath(null);
      }
    }
   
    public String getVarPrefix() {
        return reg.getKey() + "_";
    }
   
    @CodeCompletion
    public TMLPortlet getsourceportlet(PortletEvent event) throws WGAPIException {
        return getportlet(event.getSource());
    }

}
TOP

Related Classes of de.innovationgate.wgpublisher.webtml.utils.TMLPortlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.