Package org.jasig.portal

Source Code of org.jasig.portal.ChannelRegistryManager

/* Copyright 2001 The JA-SIG Collaborative.  All rights reserved.
*  See license distributed with this file and
*  available online at http://www.uportal.org/license.html
*/

package  org.jasig.portal;

import java.util.Date;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;


import org.jasig.portal.groups.IEntity;
import org.jasig.portal.groups.IEntityGroup;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.properties.PropertiesManager;
import org.jasig.portal.security.IAuthorizationPrincipal;
import org.jasig.portal.security.IPermission;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.IUpdatingPermissionManager;
import org.jasig.portal.services.AuthorizationService;
import org.jasig.portal.services.GroupService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.services.StatsRecorder;
import org.jasig.portal.utils.CommonUtils;
import org.jasig.portal.utils.DocumentFactory;
import org.jasig.portal.utils.ResourceLoader;
import org.jasig.portal.utils.SmartCache;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
* Manages the channel registry which is a listing of published channels
* that one can subscribe to (add to their layout).
* Also currently manages the channel types data and CPD documents.
* (maybe these should be managed by another class  -Ken)
* @author Ken Weiner, kweiner@unicon.net
* @version $Revision: 1.54 $
*/
public class ChannelRegistryManager {
   
    private static final Log log = LogFactory.getLog(ChannelRegistryManager.class);
   
  protected static final IChannelRegistryStore crs = ChannelRegistryStoreFactory.getChannelRegistryStoreImpl();

  /**
     * Default value for registryCacheTimeout.
     * This value will be used when the corresponding property cannot be loaded.
     */
    private static final int DEFAULT_REGISTRY_CACHE_TIMEOUT = 900;
   
    /**
     * Default value for chanTypesCacheTimeout.
     * This value will be used when the corresponding property cannot be loaded.
     */
    private static final int DEFAULT_CHAN_TYPES_CACHE_TIMEOUT = 900;
   
    /**
     * Default value for cpdCacheTimeout.
     * This value will be used when the corresponding property cannot be loaded.
     */
    private static final int DEFAULT_CPD_CACHE_TIMEOUT = 900;
   
    /**
     * Default value for localeAware.
     * This value will be used when the corresponding property cannot be loaded.
     */
    private static final boolean DEFAULT_LOCALE_AWARE = false;

  // Cache timeout properties
  /**
   * Timeout, in seconds, of the cache of the registry of channels.
   */
  protected static final int registryCacheTimeout = PropertiesManager.getPropertyAsInt("org.jasig.portal.ChannelRegistryManager.channel_registry_cache_timeout", DEFAULT_REGISTRY_CACHE_TIMEOUT);

  /**
   * Timeout, in seconds, of the cache of channel types.
   */
  protected static final int chanTypesCacheTimeout = PropertiesManager.getPropertyAsInt("org.jasig.portal.ChannelRegistryManager.channel_types_cache_timeout", DEFAULT_CHAN_TYPES_CACHE_TIMEOUT);

  /**
   * Timeout, in seconds, of the cache of channel publishing documents.
   */
  protected static final int cpdCacheTimeout = PropertiesManager.getPropertyAsInt("org.jasig.portal.ChannelRegistryManager.cpd_cache_timeout", DEFAULT_CPD_CACHE_TIMEOUT);

  // i18n properties
 
  /**
   * Boolean indicating whether internationalization will be used.
   */
  protected static final boolean localeAware = PropertiesManager.getPropertyAsBoolean("org.jasig.portal.i18n.LocaleManager.locale_aware", DEFAULT_LOCALE_AWARE);

 
 
  // Caches
  protected static final SmartCache channelRegistryCache = new SmartCache(registryCacheTimeout);
  protected static final SmartCache channelTypesCache = new SmartCache(chanTypesCacheTimeout);
  protected static final SmartCache cpdCache = new SmartCache(cpdCacheTimeout);

  // Cache keys
  private static final String CHANNEL_REGISTRY_CACHE_KEY = "channelRegistryCacheKey";
  private static final String CHANNEL_TYPES_CACHE_KEY = "channelTypesCacheKey";
  private static final String CPD_CACHE_KEY = "cpdCacheKey";

  // Permission constants
  private static final String FRAMEWORK_OWNER = "UP_FRAMEWORK";
  private static final String SUBSCRIBER_ACTIVITY = "SUBSCRIBE";
  private static final String GRANT_PERMISSION_TYPE = "GRANT";

  /**
   * Returns a copy of the channel registry as a Document.
   * This document is not filtered according to a user's channel permissions.
   * For a filtered list, see  <code>getChannelRegistry(IPerson person)</code>
   * @return a copy of the channel registry as a Document
   */
  public static Document getChannelRegistry() throws PortalException {
    Document channelRegistry = (Document)channelRegistryCache.get(CHANNEL_REGISTRY_CACHE_KEY);
    if (channelRegistry == null) {
      // Channel registry has expired, so get it and cache it
      try {
        channelRegistry = getChannelRegistryXML();
      } catch (Exception e) {
        throw new PortalException(e);
      }

      if (channelRegistry != null) {
        channelRegistryCache.put(CHANNEL_REGISTRY_CACHE_KEY, channelRegistry);
        log.info( "Caching channel registry.");
      }
    }

    // Clone the original registry document so that it doesn't get modified
    return (Document)channelRegistry.cloneNode(true);
  }

  /**
   * Returns the channel registry as a Document.  This document is filtered
   * according to a user's channel permissions.
   * @return the filtered channel registry as a Document
   */
  public static Document getChannelRegistry(IPerson person) throws PortalException {
    Document channelRegistry = getChannelRegistry();

    // Filter the channel registry according to permissions
    EntityIdentifier ei = person.getEntityIdentifier();
    IAuthorizationPrincipal ap = AuthorizationService.instance().newPrincipal(ei.getKey(), ei.getType());

    // Cycle through all the channels, looking for restricted channels
    NodeList nl = channelRegistry.getElementsByTagName("channel");
    for (int i = (nl.getLength()-1); i >=0; i--) {
      Element channel = (Element)nl.item(i);
      String channelPublishId = channel.getAttribute("chanID");
      channelPublishId = channelPublishId.startsWith("chan") ? channelPublishId.substring(4) : channelPublishId;

      // Take out channels which user doesn't have access to
      if (!ap.canSubscribe(Integer.parseInt(channelPublishId)))
        channel.getParentNode().removeChild(channel);
    }

    return channelRegistry;
  }

  /**
   * Returns an XML document which describes the channel registry.
   * See uPortal's <code>channelRegistry.dtd</code>
   * @return doc the channel registry document
   * @throws java.lang.Exception
   */
  public static Document getChannelRegistryXML() throws Exception {
    Document doc = DocumentFactory.getNewDocument();
    Element registry = doc.createElement("registry");
    doc.appendChild(registry);

    IEntityGroup channelCategoriesGroup = GroupService.getDistinguishedGroup(GroupService.CHANNEL_CATEGORIES);
    processGroupsRecursively(channelCategoriesGroup, doc, registry);

    return doc;
  }

  private static void processGroupsRecursively(IEntityGroup group,
    Document owner, Element parentGroup) throws Exception {
    Date now = new Date();
    Iterator iter = group.getMembers();
    while (iter.hasNext()) {
      IGroupMember member = (IGroupMember)iter.next();
      if (member.isGroup()) {
        IEntityGroup memberGroup = (IEntityGroup)member;
        String key = memberGroup.getKey();
        String name = memberGroup.getName();
        String description = memberGroup.getDescription();

        // Create category element and append it to its parent
        Element categoryE = owner.createElement("category");
        categoryE.setAttribute("ID", "cat" + key);
        categoryE.setIdAttribute("ID", true);
        categoryE.setAttribute("name", name);
        categoryE.setAttribute("description", description);
        parentGroup.appendChild(categoryE);
        processGroupsRecursively(memberGroup, owner, categoryE);
      } else {
        IEntity channelDefMember = (IEntity)member;
        int channelPublishId = CommonUtils.parseInt(channelDefMember.getKey());
        if ( channelPublishId > 0 ) {
         ChannelDefinition channelDef = crs.getChannelDefinition(channelPublishId);
         if (channelDef != null) {
          // Make sure channel is approved
          Date approvalDate = channelDef.getApprovalDate();
          if (approvalDate != null && approvalDate.before(now)) {
            Element channelDefE = channelDef.getDocument(owner, "chan" + channelPublishId);
            channelDefE = (Element)owner.importNode(channelDefE, true);
           
            if (channelDefE.getAttribute("ID") != null)
                channelDefE.setIdAttribute("ID", true);
           
            parentGroup.appendChild(channelDefE);
          }
         }
        }
      }
    }
  }

  /**
   * Looks in channel registry for a channel element matching the
   * given channel ID.
   * @param channelPublishId the channel publish id
   * @return the channel element matching specified channel publish id
   * @throws PortalException
   */
  public static Element getChannel (String channelPublishId) throws PortalException {
    Document channelRegistry = getChannelRegistry();
    Element channelE = null;
    try {
        String expression = "(//channel[@ID = '" + channelPublishId + "'])[1]";
        XPathFactory fac = XPathFactory.newInstance();
        XPath xpath = fac.newXPath();
        channelE = (Element) xpath.evaluate(expression, channelRegistry,
                XPathConstants.NODE);
    } catch (XPathExpressionException e) {
      throw new GeneralRenderingException("Not able to find channel " + channelPublishId + " within channel registry.", e);
    }
    return channelE;
  }

  /**
   * Create XML representing this channel definition.
   * I don't think this method really belongs in the
   * ChannelRegistryManager since this XML fragment is
   * related more to a channel instance, but we'll hold
   * it here for now and find a better place for it later :)
   * @param subscribeId the channel subscibe ID, formerly called instance ID
   * @param channelDef a channel definition
   * @return the XML representing this channel definition
   */
  public static Element getChannelXML(String subscribeId, ChannelDefinition channelDef) {
    Document doc = DocumentFactory.getNewDocument();
    Element channelE = doc.createElement("channel");
    channelE.setAttribute("ID", subscribeId);
    channelE.setAttribute("chanID", String.valueOf(channelDef.getId()));
    channelE.setAttribute("timeout", String.valueOf(channelDef.getTimeout()));
    // I18n
    if (localeAware) {
        String locale=channelDef.getLocale();
        channelE.setAttribute("name", channelDef.getName(locale));
        channelE.setAttribute("title", channelDef.getTitle(locale));
        channelE.setAttribute("locale", locale);
        if (log.isDebugEnabled())
            log.debug("ChannelRegistryManager::getChannelXML: locale=" + locale);
    else {
        channelE.setAttribute("name", channelDef.getName());
        channelE.setAttribute("title", channelDef.getTitle());
    }
    channelE.setAttribute("fname", channelDef.getFName());
    channelE.setAttribute("class", channelDef.getJavaClass());
    channelE.setAttribute("typeID", String.valueOf(channelDef.getTypeId()));
    channelE.setAttribute("editable", channelDef.isEditable() ? "true" : "false");
    channelE.setAttribute("hasHelp", channelDef.hasHelp() ? "true" : "false");
    channelE.setAttribute("hasAbout", channelDef.hasAbout() ? "true" : "false");
    channelE.setAttribute("secure", channelDef.isSecure() ? "true" : "false");
    channelE.setAttribute("isPortlet", channelDef.isPortlet() ? "true" : "false");
   
    // Add any parameters
    ChannelParameter[] parameters = channelDef.getParameters();
    for (int i = 0; i < parameters.length; i++) {
      ChannelParameter cp = parameters[i];
      Element parameterE = doc.createElement("parameter");
      parameterE.setAttribute("name", cp.getName());
      parameterE.setAttribute("value", cp.getValue());
      if (cp.getOverride()) {
        parameterE.setAttribute("override", "yes");
      }
      channelE.appendChild(parameterE);
    }

    return channelE;
  }

  /**
   * Update a channel definition with data from a channel XML
   * element.  I don't think this method really belongs in the
   * ChannelRegistryManager since this XML fragment contains
   * a channel subscribe ID, but we'll hold it here for now
   * and find a better place for it later :)
   * Note that this method does not set the ID, publisher ID,
   * approver ID, pubish date, or approval date.
   * @param channelE an XML element representing a channel definition
   * @param channelDef the channel definition to update
   */
  public static void setChannelXML(Element channelE, ChannelDefinition channelDef) {
    channelDef.setFName(channelE.getAttribute("fname"));
    channelDef.setName(channelE.getAttribute("name"));
    channelDef.setDescription(channelE.getAttribute("description"));
    channelDef.setTitle(channelE.getAttribute("title"));
    channelDef.setJavaClass(channelE.getAttribute("class"));

    String timeout = channelE.getAttribute("timeout");
    if (timeout != null && timeout.trim().length() != 0) {
      channelDef.setTimeout(Integer.parseInt(timeout));
    }

    String secure = channelE.getAttribute("secure");
    channelDef.setIsSecure(secure != null && secure.equals("true") ? true : false);
   
    channelDef.setTypeId(Integer.parseInt(channelE.getAttribute("typeID")));
    String chanEditable = channelE.getAttribute("editable");
    String chanHasHelp = channelE.getAttribute("hasHelp");
    String chanHasAbout = channelE.getAttribute("hasAbout");
    channelDef.setEditable(chanEditable != null && chanEditable.equals("true") ? true : false);
    channelDef.setHasHelp(chanHasHelp != null && chanHasHelp.equals("true") ? true : false);
    channelDef.setHasAbout(chanHasAbout != null && chanHasAbout.equals("true") ? true : false);
    // I18n
    if (localeAware) {
        channelDef.setLocale(channelE.getAttribute("locale"));
    }

    // Now set the channel parameters
    channelDef.clearParameters();
    NodeList channelChildren = channelE.getChildNodes();
    if (channelChildren != null) {
      for (int i = 0; i < channelChildren.getLength(); i++) {
        if (channelChildren.item(i).getNodeName().equals("parameter")) {
          Element parameterE = (Element)channelChildren.item(i);
          NamedNodeMap parameterAtts = parameterE.getAttributes();
          String paramName = null;
          String paramValue = null;
          String paramOverride = "NULL";

          for (int j = 0; j < parameterAtts.getLength(); j++) {
            Node parameterAtt = parameterAtts.item(j);
            String parameterAttName = parameterAtt.getNodeName();
            String parameterAttValue = parameterAtt.getNodeValue();

            if (parameterAttName.equals("name")) {
              paramName = parameterAttValue;
            } else if (parameterAttName.equals("value")) {
              paramValue = parameterAttValue;
            } else if (parameterAttName.equals("override") && parameterAttValue.equals("yes")) {
              paramOverride = "Y";
            }
          }

          if (paramName == null && paramValue == null) {
            throw new RuntimeException("Invalid parameter node");
          }

          channelDef.addParameter(paramName, paramValue, paramOverride);
        }
      }
    }
  }

  /**
   * Create XML representing the channel types.
   * It will look something like this:
   * <p><code>
   *
   *<channelTypes>
   <channelType ID="0">
   *    <class>org.jasig.portal.channels.CImage</class>
   *    <name>Image</name>
   *    <description>Simple channel to display an image with optional
   *        caption and subcaption</description>
   *    <cpd-uri>webpages/media/org/jasig/portal/channels/CImage/CImage.cpd</cpd-uri>
   </channelType>
   <channelType ID="1">
   *    <class>org.jasig.portal.channels.CWebProxy</class>
   *    <name>Web Proxy</name>
   *    <description>Incorporate a dynamic HTML or XML application</description>
   *    <cpd-uri>webpages/media/org/jasig/portal/channels/CWebProxy/CWebProxy.cpd</cpd-uri>
   </channelType>
   *</channelTypes>
   *
   * </code></p>
   * @return channelTypesXML, the XML representing the channel types
   * @throws java.lang.Exception
   */
  public static Document getChannelTypesXML() throws Exception {
    Document doc = DocumentFactory.getNewDocument();
    Element channelTypesE = doc.createElement("channelTypes");

    ChannelType[] channelTypes = crs.getChannelTypes();
    for (int i = 0; i < channelTypes.length; i++) {
      int channelTypeId = channelTypes[i].getId();
      String javaClass = channelTypes[i].getJavaClass();
      String name = channelTypes[i].getName();
      String descr = channelTypes[i].getDescription();
      String cpdUri = channelTypes[i].getCpdUri();

      // <channelType>
      Element channelTypeE = doc.createElement("channelType");
      channelTypeE.setAttribute("ID", String.valueOf(channelTypeId));

      // <class>
      Element classE = doc.createElement("class");
      classE.appendChild(doc.createTextNode(javaClass));
      channelTypeE.appendChild(classE);

      // <name>
      Element nameE = doc.createElement("name");
      nameE.appendChild(doc.createTextNode(name));
      channelTypeE.appendChild(nameE);

      // <description>
      Element descriptionE = doc.createElement("description");
      descriptionE.appendChild(doc.createTextNode(descr));
      channelTypeE.appendChild(descriptionE);

      // <cpd-uri>
      Element cpdUriE = doc.createElement("cpd-uri");
      cpdUriE.appendChild(doc.createTextNode(cpdUri));
      channelTypeE.appendChild(cpdUriE);

      channelTypesE.appendChild(channelTypeE);
    }
    doc.appendChild(channelTypesE);

    return doc;
  }

  /**
   * Looks in channel registry for a channel element matching the
   * given channel ID.
   * @param channelPublishId the channel publish ID
   * @return the channel element matching chanID
   * @throws org.jasig.portal.PortalException
   */
  public static NodeList getCategories(String channelPublishId) throws PortalException {
    Document channelRegistry = (Document)channelRegistryCache.get(CHANNEL_REGISTRY_CACHE_KEY);
    NodeList categories = null;
    try {
        String expression = "//category[channel/@ID = '" + channelPublishId + "']";
        XPathFactory fac = XPathFactory.newInstance();
        XPath xpath = fac.newXPath();
        categories = (NodeList) xpath.evaluate(expression, channelRegistry, XPathConstants.NODESET);
       
    } catch (XPathExpressionException e) {
        throw new GeneralRenderingException("Not able to find channel " + channelPublishId + " within channel registry.", e);
    }
    return categories;
  }

  /**
   * Publishes a channel.
   * @param channel the channel XML fragment
   * @param categoryIDs a list of categories that the channel belongs to
   * @param groupMembers a list of groups and/or people that are permitted to subscribe to and view the channel
   * @param publisher the user ID of the channel publisher
   * @throws java.lang.Exception
   */
  public static void publishChannel (Element channel, String[] categoryIDs, IGroupMember[] groupMembers, IPerson publisher) throws Exception {
    // Reset the channel registry cache
    channelRegistryCache.remove(CHANNEL_REGISTRY_CACHE_KEY);

    ChannelDefinition channelDef = null;

    // Use current channel ID if modifying previously published channel, otherwise get a new ID
    boolean newChannel = true;
    int ID = 0;
    String channelPublishId = channel.getAttribute("ID");
    if (channelPublishId != null && channelPublishId.trim().length() > 0) {
      newChannel = false;
      ID = Integer.parseInt(channelPublishId.startsWith("chan") ? channelPublishId.substring(4) : channelPublishId);
      channelDef = crs.getChannelDefinition(ID);
      if (log.isDebugEnabled())
          log.debug("Attempting to modify channel " + ID + "...");
    }
    else {
      channelDef = crs.newChannelDefinition();
      ID = channelDef.getId();
      if (log.isDebugEnabled())
          log.debug("Attempting to publish new channel " + ID + "...");
    }

    // Add channel
    setChannelXML(channel, channelDef);
    Date now = new Date();
    channelDef.setPublisherId(publisher.getID());
    channelDef.setPublishDate(now);
    channelDef.setApproverId(publisher.getID());
    channelDef.setApprovalDate(now);
    crs.saveChannelDefinition(channelDef);

    // Delete existing category memberships for this channel  
    String chanKey = String.valueOf(channelDef.getId());
    IEntity channelDefEntity = GroupService.getEntity(chanKey, ChannelDefinition.class);
    Iterator iter = channelDefEntity.getAllContainingGroups();
    while (iter.hasNext()) {
        IEntityGroup group = (IEntityGroup) iter.next();
        group.removeMember(channelDefEntity);
        group.update();
    }

    // For each category ID, add channel to category
    for (int i = 0; i < categoryIDs.length; i++) {
      categoryIDs[i] = categoryIDs[i].startsWith("cat") ? categoryIDs[i].substring(3) : categoryIDs[i];
      String iCatID = categoryIDs[i];
      ChannelCategory category = crs.getChannelCategory(iCatID);
      crs.addChannelToCategory(channelDef, category);
    }

    // Set groups
    AuthorizationService authService = AuthorizationService.instance();
    String target = "CHAN_ID." + ID;
    IUpdatingPermissionManager upm = authService.newUpdatingPermissionManager(FRAMEWORK_OWNER);
    IPermission[] permissions = new IPermission[groupMembers.length];
    for (int i = 0; i < groupMembers.length; i++) {
      IAuthorizationPrincipal authPrincipal = authService.newPrincipal(groupMembers[i]);
      permissions[i] = upm.newPermission(authPrincipal);
      permissions[i].setType(GRANT_PERMISSION_TYPE);
      permissions[i].setActivity(SUBSCRIBER_ACTIVITY);
      permissions[i].setTarget(target);
    }

    // If modifying the channel, remove the existing permissions before adding the new ones
    if (!newChannel) {
      IPermission[] oldPermissions = upm.getPermissions(SUBSCRIBER_ACTIVITY, target);
      upm.removePermissions(oldPermissions);
    }
    upm.addPermissions(permissions);

    if (log.isInfoEnabled())
        log.info( "Channel " + ID + " has been " +
                (newChannel ? "published" : "modified") + ".");

    // Record that a channel has been published or modified
    if (newChannel)
      StatsRecorder.recordChannelDefinitionPublished(publisher, channelDef);
    else
      StatsRecorder.recordChannelDefinitionModified(publisher, channelDef);
  }

  /**
   * Removes a channel from the channel registry.
   * @param channelID the channel ID
   * @param person the person removing the channel
   * @throws java.lang.Exception
   */
  public static void removeChannel (String channelID, IPerson person) throws Exception {
    // Reset the channel registry cache
    channelRegistryCache.remove(CHANNEL_REGISTRY_CACHE_KEY);
    // Remove the channel
    String sChannelPublishId = channelID.startsWith("chan") ? channelID.substring(4) : channelID;
    int channelPublishId = Integer.parseInt(sChannelPublishId);
    ChannelDefinition channelDef = crs.getChannelDefinition(channelPublishId);
    crs.disapproveChannelDefinition(channelDef);

    // Record that a channel has been deleted
    StatsRecorder.recordChannelDefinitionRemoved(person, channelDef);
  }

  /**
   * Returns the publishable channel types as a Document.
   * @return a list of channel types as a Document
   */
  public static Document getChannelTypes() throws PortalException {
    Document channelTypes = (Document)channelTypesCache.get(CHANNEL_TYPES_CACHE_KEY);
    if (channelTypes == null)
    {
      // Channel types doc has expired, so get it and cache it
      try {
        channelTypes = getChannelTypesXML();
      } catch (Exception e) {
        throw new PortalException(e);
      }

      if (channelTypes != null)
      {
        channelTypesCache.put(CHANNEL_TYPES_CACHE_KEY, channelTypes);
        if (log.isInfoEnabled())
            log.info( "Caching channel types.");
      }
    }

    // Clone the original channel types document so that it doesn't get modified
    return (Document)channelTypes.cloneNode(true);
  }

  /**
   * Returns a CPD (channel publishing document) as a Document
   * @param chanTypeID the channel type ID, "-1" if channel type is "custom"
   * @return the CPD document matching the chanTypeID, <code>null</code> if "custom" channel
   * @throws org.jasig.portal.PortalException
   */
  public static Document getCPD(String chanTypeID) throws PortalException {
    //  There are no CPD docs for custom channels (chanTypeID = -1)
    if (chanTypeID == null || chanTypeID.equals("-1"))
      return null;

    Document cpd = (Document)cpdCache.get(CPD_CACHE_KEY + chanTypeID);
    if (cpd == null) {
      // CPD doc has expired, so get it and cache it
      Element channelTypes = getChannelTypes().getDocumentElement();

      // Look for channel type element matching the channel type ID
      Element chanType = null;

      for (Node n = channelTypes.getFirstChild(); n != null; n = n.getNextSibling()) {
        if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals("channelType")) {
          chanType = (Element)n;
          if (chanTypeID.equals(chanType.getAttribute("ID")))
            break;
        }
      }

      // Find the cpd-uri within this element
      String cpdUri = null;
      for (Node n = chanType.getLastChild(); n != null; n = n.getPreviousSibling()) {
        if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals("cpd-uri")) {
          // Found the <cpd-uri> element, now get its value
          for (Node m = n.getFirstChild(); m != null; m = m.getNextSibling()) {
            if (m instanceof Text)
              cpdUri = m.getNodeValue();
          }
          break;
        }
      }

      if (cpdUri != null) {
        try {
          cpd = ResourceLoader.getResourceAsDocument(ChannelRegistryManager.class, cpdUri);
        } catch (java.io.IOException ioe) {
          throw new ResourceMissingException(cpdUri, "Channel publishing document", ioe);
        } catch (org.xml.sax.SAXException se) {
          throw new PortalException("Unable to parse CPD file: " + cpdUri, se);
        } catch (ParserConfigurationException pce) {
          throw new PortalException("Unable to parse CPD file: " + cpdUri, pce);
        }
      }

      if (cpd != null) {
        cpdCache.put(CPD_CACHE_KEY + chanTypeID, cpd);
        if (log.isInfoEnabled())
            log.info( "Caching CPD for channel type " + chanTypeID);
      }
    }

    // Clone the original CPD document so that it doesn't get modified
    return (Document)cpd.cloneNode(true);
  }
}





TOP

Related Classes of org.jasig.portal.ChannelRegistryManager

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.