Package de.innovationgate.webgate.api.jdbc

Source Code of de.innovationgate.webgate.api.jdbc.PortletRegistryImplV4

/*******************************************************************************
* 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.webgate.api.jdbc;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import de.bannkreis.groq.Groq;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGBackendException;
import de.innovationgate.webgate.api.WGIllegalArgumentException;
import de.innovationgate.webgate.api.WGPortlet;
import de.innovationgate.webgate.api.WGPortletDefaultBean;
import de.innovationgate.webgate.api.WGPortletRegistry;
import de.innovationgate.webgate.api.WGSystemException;
import de.innovationgate.webgate.api.WGUserProfile;
import de.innovationgate.wga.common.ImmutableObject;
import de.innovationgate.wga.common.beans.csconfig.v1.Version;

public class PortletRegistryImplV4 extends WGPortletRegistry implements ImmutableObject {
   
    public static final DecimalFormat PORTLETINDEX_FORMAT = new DecimalFormat("000");
   
    public static final Pattern PATTERN_OLD_STYLE_PORTLETKEY = Pattern.compile("^p\\d+$");
   
    public static String buildNamespacePrefix(String dbkey) {
       
        dbkey = dbkey.toLowerCase();
        String prefix = StringUtils.left(dbkey, 1) + StringUtils.right(dbkey, 2);
        if (prefix.length() < 3) {
            prefix += StringUtils.repeat("x", 3 - prefix.length());
        }
       
        // Escape non alphanumeric characters as x
        char[] chars = prefix.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (!Character.isLetterOrDigit(chars[i])) {
                chars[i] = 'x';
            }
        }
       
        return new String(chars);
       
    }
   
   
    private WGDatabaseImpl _parent;
    private UserProfile _profile;
    private WGDocumentImpl _docImpl;

    public PortletRegistryImplV4(WGDatabaseImpl parent, WGDocumentImpl docImpl) {
        _parent = parent;
        _docImpl = docImpl;
        _profile = (UserProfile) docImpl.getNativeObject();
    }

    public synchronized void insertPortlet(WGPortlet portlet) throws WGAPIException {
       
        if (portlet.isRoot()) {
            throw new WGIllegalArgumentException("Cannot insert a root portlet");   
        }

       
       
        List portletKeys = getPortletIds(portlet.getApplicationDb());
        if (portlet.getParentPortletKey() != null && !isRootPortletKey(portlet.getParentPortletKey()) && !portletKeys.contains(portlet.getParentPortletKey())) {
            throw new IllegalStateException("Cannot register portlet for parent '" + portlet.getParentPortletKey() + "' because the parent portlet is not registered");
        }
       
        synchronized (this) {
            // Generate portlet key
            String childPortletKey = generateNewPortletKey(portlet.getApplicationDb());
   
            // Register portlet
            WGPortletDefaultBean portletBean = (WGPortletDefaultBean) portlet;
            insertPortletId(portletBean, childPortletKey);
            _profile.getPortletkeys().add(serializePortlet(portlet));
        }
       
    }

    public WGPortlet getPortlet(String appDb, String key) throws WGAPIException {
       
       
        if (isRootPortletKey(key)) {
            return getRootPortlet(appDb);
        }
       
        Iterator<String> regs = _profile.getPortletkeys().iterator();
        while (regs.hasNext()) {
            String reg = (String) regs.next();
            WGPortlet portlet = deserializePortlet(reg, appDb);
           
            // We do not need to check appDb here bc. in this portlet registry impl the appDb is implicitly contained in the portlet key
            if (portlet.getKey().equals(key)) {
                return portlet;
            }
        }
       
        return null;
    }

    private boolean isRootPortletKey(String key) {
       
        if (key.equals("")) {
            return true;
        }
       
        if (key.length() == 6) {
            try {
                String indexStr = key.substring(3);
                Number index = PORTLETINDEX_FORMAT.parse(indexStr);
                if (index.intValue() == 0) {
                    return true;
                }
            }
            catch (Exception e) {
            }
        }
       
        return false;
    }

    public List<String> getPortletIds(String appDb) throws WGAPIException {
       
        Iterator<String> regs = _profile.getPortletkeys().iterator();
        List<String> keys = new ArrayList<String>();
       
        while (regs.hasNext()) {
            String reg = (String) regs.next();
            WGPortlet portlet = deserializePortlet(reg, appDb);
            if (doesPortletKeyMatchAppDb(appDb, portlet)) {
                keys.add(portlet.getKey());
            }
        }
        return keys;
    }
   

   


    private boolean doesPortletKeyMatchAppDb(String appDb, WGPortlet portlet) {
        boolean matchesAppDb = false;
       
        String expectedKeyPrefix = buildNamespacePrefix(appDb);
       
        if (portlet.getKey().startsWith(expectedKeyPrefix)) {
            matchesAppDb = true;
        }
        // Check for old style portlet registrations - Here we cannot determine if the portletkey matches any application
        else if (PATTERN_OLD_STYLE_PORTLETKEY.matcher(portlet.getKey()).matches()) {
            matchesAppDb = true;
        }
        return matchesAppDb;
    }

    public void removePortlet(WGPortlet portlet) throws WGAPIException {
       
        if (portlet.isRoot()) {
            throw new WGIllegalArgumentException("Cannot remove the root portlet");   
        }
       
        // First unregister child portlets
        Iterator<WGPortlet> children = getChildPortlets(portlet).iterator();
        while (children.hasNext()) {
            WGPortlet child = (WGPortlet) children.next();
            removePortlet(child);
        }
       
        // Cleanup all items
        clearItems(portlet);
       
        // Remove registration
        Iterator<String> regs = _profile.getPortletkeys().iterator();
        while (regs.hasNext()) {
            String reg = (String) regs.next();
            WGPortlet p = deserializePortlet(reg, portlet.getApplicationDb());
           
            // We do not need to check appDb here bc. in this portlet registry impl the appDb is implicitly contained in the portlet key
            if (p.getKey().equals(portlet.getKey())) {
                regs.remove();
            }
        }
    }
   
    private synchronized String generateNewPortletKey(String appDb) throws WGAPIException {
       
        String charPart = buildNamespacePrefix(appDb);
               
        // Find the last portlet key with this prefix
        int portletIndex = 0;
        List portletKeys = getPortletIds(appDb);
        if (!portletKeys.isEmpty()) {
            Iterator iter = portletKeys.iterator();

            while (iter.hasNext()) {
                String pkey = (String) iter.next();
                if (pkey.startsWith(charPart)) {
                    int tempValue = Integer.parseInt(pkey.substring(charPart.length()));
                    if (portletIndex < tempValue) {
                        portletIndex = tempValue;
                    }
                }
            }
        }
       
        portletIndex++;
        return charPart + PORTLETINDEX_FORMAT.format(portletIndex);
    }
   
    private String serializePortlet(WGPortlet portlet) {
       
        List elements = new ArrayList();
        elements.add(portlet.getKey());
        elements.add(portlet.getParentPortletKey());
       
        if (portlet.getDesignDb() != null) {
            elements.add(portlet.getDesignDb() + "/" + portlet.getDesign());
        }
        else {
            elements.add(portlet.getDesign());
        }
       
        elements.add(portlet.getName());
        return WGUtils.serializeCollection(elements, "|", null, true);
       
    }
   
    private WGPortletDefaultBean deserializePortlet(String portletRegistration, String appDb) {
       
        //  getting Indizes of delimiters
        List regElements = WGUtils.deserializeCollection(portletRegistration, "|");
        if (regElements.size() < 4) {
            throw new IllegalArgumentException("Portlet registration elements are " + regElements.size() + ", must be at least 4: " + portletRegistration);
        }

        // separate string into components
       
        String key  = (String) regElements.get(0);
        String parentPortletId = (String) regElements.get(1);
        WGPortletDefaultBean portlet = createPortletDefaultBean(key, appDb, parentPortletId);
       
        String db = null;
        String design = (String) regElements.get(2);
       
        int slashPos = design.indexOf("/");
       
        // Extract database if available
        if (slashPos != -1) {
            db = design.substring(0, slashPos);
            design = design.substring(slashPos + 1);
        }
        String title = (String) regElements.get(3);
       
        portlet.setDesignDb(db);
        portlet.setDesign(design);
        portlet.setName(title);
       
        return portlet;
       
       
    }

    @Override
    public void updatePortlet(WGPortlet portletToUpdate) throws WGIllegalArgumentException {
       
        if (portletToUpdate.isRoot()) {
            throw new WGIllegalArgumentException("Cannot update the root portlet");   
        }
       
        List regs = _profile.getPortletkeys();
        for (int idx=0; idx < regs.size(); idx++) {
            String reg = (String) regs.get(idx);
            WGPortlet portlet = deserializePortlet(reg, portletToUpdate.getApplicationDb());
           
            // We do not need to check appDb here bc. in this portlet registry impl the appDb is implicitly contained in the portlet key
            if (portlet.getKey().equals(portletToUpdate.getKey())) {
                regs.set(idx, serializePortlet(portletToUpdate));
                return;
            }
        }
       
        throw new WGIllegalArgumentException("No portlet of id '" + portletToUpdate.getKey() + "' has yet been registered");
    }

    @Override
    public List<WGPortlet> getChildPortlets(WGPortlet parent) throws WGAPIException {

        List<WGPortlet> children = new ArrayList<WGPortlet>();
       
        List regs = _profile.getPortletkeys();
        for (int idx=0; idx < regs.size(); idx++) {
            String reg = (String) regs.get(idx);
            WGPortletDefaultBean portlet = deserializePortlet(reg, parent.getApplicationDb());
           
            if (parent.getKey().equals(portlet.getParentPortletKey())) {
                children.add(portlet);
            }
        }
       
        return children;
       
       
    }

    @Override
    public WGPortlet getRootPortlet(String dbKey) throws WGAPIException {
        String rootNS = determineRootPortletNamespace(dbKey);
        return createPortletDefaultBean(rootNS, dbKey, null);
    }
   
    private String determineRootPortletNamespace(String dbKey) throws WGAPIException {
       
        UserProfileItem wgaCreationVersion = (UserProfileItem) _profile.getItems().get(WGUserProfile.ITEM_WGACREATIONVERSION);
        if (wgaCreationVersion != null) {
            Version version = new Version(wgaCreationVersion.getText());
           
            // From WGA Version 4.1 on the root portlet has a defined namespace, based on the dbkey of the main context, plus index number 000.
            if (version.isAtLeast(4, 1)) {
                String nsPrefix = buildNamespacePrefix(dbKey);
                return nsPrefix + "000";
            }
        }
       
        // For earlier WGA versions the root portlet has an empty string namespace
        // (which is problematic when multiple portlet application dbs share the same perso db)
        return "";
    }

    @Override
    public void prepareNewProfile(WGUserProfile profile) throws WGAPIException {
    }

    @Override
    public List<String> getItemNames(WGPortlet portlet) {
       
        String itemPrefix = getItemPrefix(portlet);
        List<String> list = Groq
        .selectFrom(_profile.getItems().keySet())
        .whereStartsWith(itemPrefix)
        .substring(itemPrefix.length());
        return list;
    }

    @Override
    public Object getItemValue(WGPortlet portlet, String name) throws WGSystemException, WGBackendException {
        return _docImpl.getItemValue(getItemPrefix(portlet) + name);
    }

    @Override
    public void removeItem(WGPortlet portlet, String name) throws WGIllegalArgumentException {
        _docImpl.removeItem(getItemPrefix(portlet) + name);
       
    }

    @Override
    public void setItemValue(WGPortlet portlet, String name, Object value) throws WGIllegalArgumentException, WGSystemException {
        _docImpl.setItemValue(getItemPrefix(portlet) + name, value);
       
    }
   
    private String getItemPrefix(WGPortlet portlet) {
        return portlet.getKey() + "_";
    }

    @Override
    public boolean hasItem(WGPortlet portlet, String name) throws WGAPIException {
        return _docImpl.hasItem(getItemPrefix(portlet) + name);
    }

    @Override
    public WGPortlet createPortlet(String appDb, WGPortlet parent) {
        return createPortletDefaultBean(null, appDb, (parent != null ? parent.getKey() : null));
    }
   

    @Override
    public Set<String> getAppDbs() {

        Set<String> apps = new HashSet<String>();
       
        List regs = _profile.getPortletkeys();
        boolean oldStylePresent = false;
       
        for (int idx=0; idx < regs.size(); idx++) {
            String reg = (String) regs.get(idx);
            WGPortletDefaultBean portlet = deserializePortlet(reg, "");
            if (!PATTERN_OLD_STYLE_PORTLETKEY.matcher(portlet.getKey()).matches()) {
                String app = portlet.getKey().substring(0, 3);
                apps.add(app);
            }
            else {
                oldStylePresent = true;
            }
           
        }
       
        return apps;
       
    }

}
TOP

Related Classes of de.innovationgate.webgate.api.jdbc.PortletRegistryImplV4

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.