All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.myfaces.trinidadinternal.skin.SkinUtils Maven / Gradle / Ivy

The newest version!
/*
 *  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.myfaces.trinidadinternal.skin;

import java.beans.Beans;

import java.io.IOException;
import java.io.InputStream;

import java.net.URL;
import java.net.URLConnection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import javax.el.ValueExpression;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.resource.SkinResourceLoader;
import org.apache.myfaces.trinidad.share.io.NameResolver;
import org.apache.myfaces.trinidad.skin.Icon;
import org.apache.myfaces.trinidad.skin.Skin;
import org.apache.myfaces.trinidad.skin.SkinAddition;
import org.apache.myfaces.trinidad.skin.SkinFactory;
import org.apache.myfaces.trinidad.skin.SkinVersion;
import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
import org.apache.myfaces.trinidadinternal.config.LazyValueExpression;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.CasablancaDesktopSkin;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.CasablancaPdaSkin;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.CasablancaPortletSkin;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.MinimalDesktopSkinExtension;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.MinimalPdaSkinExtension;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.MinimalPortletSkinExtension;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.SimpleDesktopSkin;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.SimplePdaSkin;
import org.apache.myfaces.trinidadinternal.renderkit.core.skin.SimplePortletSkin;
import org.apache.myfaces.trinidadinternal.share.xml.ClassParserFactory;
import org.apache.myfaces.trinidadinternal.share.xml.ParseContextImpl;
import org.apache.myfaces.trinidadinternal.share.xml.ParserFactory;
import org.apache.myfaces.trinidadinternal.share.xml.ParserManager;
import org.apache.myfaces.trinidadinternal.share.xml.TreeBuilder;
import org.apache.myfaces.trinidadinternal.share.xml.XMLProvider;
import org.apache.myfaces.trinidadinternal.share.xml.XMLUtils;
import org.apache.myfaces.trinidadinternal.skin.icon.ReferenceIcon;
import org.apache.myfaces.trinidadinternal.skin.parse.SkinAdditionNode;
import org.apache.myfaces.trinidadinternal.skin.parse.SkinNode;
import org.apache.myfaces.trinidadinternal.skin.parse.SkinVersionNode;
import org.apache.myfaces.trinidadinternal.skin.parse.SkinsNode;
import org.apache.myfaces.trinidadinternal.skin.parse.XMLConstants;

import org.xml.sax.InputSource;


/**
 * Utility functions for creating Skin objects and SkinExtension objects
 * from the trinidad-skins.xml file and
 * adding them to the SkinFactory. It also adds SkinAdditions to the Skin objects.
 * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/skin/SkinUtils.java#0 $) $Date: 10-nov-2005.18:59:00 $
 */
public class SkinUtils
{

  /**
   * Register the base skins with the SkinFactory. (simple/minimal)
   * Make sure the SkinFactory.getFactory() does not return null before
   * calling this method.
   */
  static public void registerBaseSkins()
  {

    SkinFactory skinFactory = SkinFactory.getFactory();

    // skinFactory should be non-null when this is called since it is
    // initiated in the TrinidadFilterImpl, but in case it isn't do this
    if (skinFactory == null)
    {
      SkinFactory.setFactory(new SkinFactoryImpl());
      skinFactory = SkinFactory.getFactory();
    }

    _registerTrinidadSkins(skinFactory);
  }

  /**
   * Register any custom skin extensions (and skin-additions) found in the
   * trinidad-skins.xml file with the SkinFactory.
   *
   * Make sure the SkinFactory.getFactory() does not return null before
   * calling this method.
   * You should call registerBaseSkins() before calling this method.
   * @param context ServletContext, used to get the trinidad-skins.xml file.
   */
  static public void registerSkinExtensions(
    ExternalContext context)
  {

    SkinFactory skinFactory = SkinFactory.getFactory();

    // skinFactory should be non-null when this is called since it is
    // initiated in the TrinidadFilterImpl, but in case it isn't do this
    if (skinFactory == null)
    {
      SkinFactory.setFactory(new SkinFactoryImpl());
      skinFactory = SkinFactory.getFactory();
    }
    boolean fine = _LOG.isFine();
    if (fine) _LOG.fine("Begin registerSkinExtensions");
    _registerSkinExtensionsAndAdditions(context, skinFactory);
    if (fine) _LOG.fine("End registerSkinExtensions");


  }

  /**
   * Returns the actual Icon referenced by the ReferenceIcon.
   * @param skin the Skin to use when resolving the ReferenceIcon
   * @param refIcon a ReferenceIcon instance
   * @return icon which is resolved. i.e., it is not a ReferenceIcon.
   */
   static public Icon resolveReferenceIcon(
     Skin          skin,
     ReferenceIcon refIcon)
   {
     return _resolveReferenceIcon(skin, refIcon, null);
   }

  /**
   * Helper for resolveReferenceIcon which uses a Stack of icon names
   * to detect circular dependencies.
   *
   * @param skin the Skin to use when resolving the ReferenceIcon
   * @param refIcon a ReferenceIcon instance
   * @param referencedIconStack  The stack of reference icon names which have
   *          already been visited.  Used to detect circular dependencies.
   * @return icon which is resolved. i.e., it is not a ReferenceIcon.
   */
  static private Icon _resolveReferenceIcon(
    Skin          skin,
    ReferenceIcon refIcon,
    Stack referencedIconStack)
  {
    String refName = refIcon.getName();

    // make sure we don't have a circular dependency
    if ((referencedIconStack != null) && referencedIconStack.contains(refName))
    {
      if (_LOG.isWarning())
        _LOG.warning("SKIN_CIRCULAR_INCLUDE_ERROR", refName);
      return null;
    }

    if (referencedIconStack == null)
    {
      referencedIconStack = new Stack();
    }

    referencedIconStack.push(refName);

    Icon icon = skin.getIcon(refName, false);

    if ((icon instanceof ReferenceIcon) && (icon != null))
    {

      return _resolveReferenceIcon(skin,
                                  (ReferenceIcon)icon,
                                  referencedIconStack);

    }

    return icon;
  }

  /**
   * Create a SkinExtension off a generic SAX input source, using
   * a custom parsing manager.
   * 

* @param provider * @param resolver A NameResolver that can be used to locate * resources, such as source images for colorized * icons. * @param parserManager the ParserManager to use for parsing * Must be non-null. * @throws NullPointerException when inputStream or parserManager * is null. */ /** * * @param provider an XMLProvider implementation. * @param resolver A NameResolver that can be used to locate * resources, such as source images for colorized * icons. * @param inputStream the inputStream. Must be non-null * @param parserManager the ParserManager to use for parsing * Must be non-null. * @param configFile The name of the config file we are parsing. * @return A SkinsNode object (contains a List of SkinNode and a List of SkinAdditionNode) */ static private SkinsNode _getSkinsNodeFromInputStream( XMLProvider provider, NameResolver resolver, InputStream inputStream, ParserManager parserManager, String configFile ) { if (inputStream == null) throw new NullPointerException(_LOG.getMessage( "NO_INPUTSTREAM")); if (parserManager == null) throw new NullPointerException(_LOG.getMessage( "NULL_PARSEMANAGER")); SkinsNode skinsNode = null; try { InputSource input = new InputSource(); input.setByteStream(inputStream); input.setPublicId(configFile); ParseContextImpl context = new ParseContextImpl(); // Set up the NameResolver if we have one if (resolver != null) XMLUtils.setResolver(context, resolver); // Create the TreeBuilder TreeBuilder builder = new TreeBuilder(parserManager, SkinsNode.class); skinsNode = ((SkinsNode)builder.parse(provider, input, context)); } catch (Exception e) { _LOG.warning("SKIN_CONFIG_PROCESS_FAILURE", configFile); _LOG.warning(e); } finally { try { inputStream.close(); } catch (IOException ioe) { // Ignore ; } } return skinsNode; } /** * Creates a ParserManager pre-registered witih all * the default ParserFactories needed to create SkinExtensions. */ static public ParserManager createDefaultManager() { ParserManager manager = new ParserManager(); // Register top-level factory _registerFactory(manager, SkinsNode.class, "SkinsNode"); // Register skin node factory and skin addition node factory _registerFactory(manager, SkinNode.class, "SkinNode"); _registerFactory(manager, SkinAdditionNode.class, "SkinAdditionNode"); _registerFactory(manager, SkinVersionNode.class, "SkinVersionNode"); return manager; } // Returns a singleton instance of the default ParserManager static private ParserManager _getDefaultManager() { if (_sManager == null) _sManager = createDefaultManager(); return _sManager; } // Registers a ParserFactory for the LAF namespace static private void _registerFactory( ParserManager manager, Class expectedType, String baseName ) { String className = _LAF_PARSE_PACKAGE + baseName + "Parser"; ParserFactory factory = new ClassParserFactory(className); manager.registerFactory(expectedType, XMLConstants.SKIN_NAMESPACE, factory); } /** * register the Trinidad skins: simpleDesktopSkin, simplePdaSkin, * and minimalDesktopSkin, minimalPdaSkin, casablancaSkin and portlet skins. * @param skinFactory */ private static void _registerTrinidadSkins( SkinFactory skinFactory) { // SimpleDesktopSkin is the BASE skin for org.apache.myfaces.trinidad.desktop renderKit // SimplePdaSkin is the BASE skin for org.apache.myfaces.trinidad.pda renderKit. By // BASE skin, I mean, this is the skin that all SkinExtensions extend // from. SimpleDesktopSkin simpleDesktopSkin = new SimpleDesktopSkin(); skinFactory.addSkin(simpleDesktopSkin.getId(), simpleDesktopSkin); SimplePdaSkin simplePdaSkin = new SimplePdaSkin(); skinFactory.addSkin(simplePdaSkin.getId(), simplePdaSkin); //portlet skin maps most of our style classes to portlet style classes, // so we output portlet style classes. // It also clears out the portlet style class definitions. SimplePortletSkin simplePortletSkin = new SimplePortletSkin(); skinFactory.addSkin(simplePortletSkin.getId(), simplePortletSkin); MinimalDesktopSkinExtension minimalDesktopSkin = new MinimalDesktopSkinExtension(simpleDesktopSkin); skinFactory.addSkin(minimalDesktopSkin.getId(), minimalDesktopSkin); MinimalPdaSkinExtension minimalPdaSkin = new MinimalPdaSkinExtension(simplePdaSkin); skinFactory.addSkin(minimalPdaSkin.getId(), minimalPdaSkin); MinimalPortletSkinExtension minimalPortletSkin = new MinimalPortletSkinExtension(simplePortletSkin); skinFactory.addSkin(minimalPortletSkin.getId(), minimalPortletSkin); CasablancaDesktopSkin casablancaDesktopSkin = new CasablancaDesktopSkin(simpleDesktopSkin); skinFactory.addSkin(casablancaDesktopSkin.getId(), casablancaDesktopSkin); CasablancaPdaSkin casablancaPdaSkin = new CasablancaPdaSkin(simplePdaSkin); skinFactory.addSkin(casablancaPdaSkin.getId(), casablancaPdaSkin); CasablancaPortletSkin casablancaPortletSkin = new CasablancaPortletSkin(simplePortletSkin); skinFactory.addSkin(casablancaPortletSkin.getId(), casablancaPortletSkin); } /** * Parse the trinidad-skins.xml file for SkinExtensions and SkinAdditionNodes and add each * SkinExtension to the skinFactory and each SkinAddition to its skin. * First find all the trinidad-skins.xml files that are in META-INF directory, and * add those skins and skin additions. * Then find the WEB-INF/trinidad-skins.xml file and add those skins and skin additions. * The skins are ordered so that the 'extended' skins are registered before the skins that extend * them. * @param context * @param skinFactory */ private static void _registerSkinExtensionsAndAdditions( ExternalContext context, SkinFactory skinFactory) { if (context == null) return; // Add META-INF/trinidad-skins.xml skins to skin factory. (sorted first to make sure // we register the most 'base' skins first) if (_LOG.isFine()) _LOG.fine("Parse META-INF/trinidad-skins.xml files"); List metaInfSkinsNodeList = _getMetaInfSkinsNodeList(); // Go through each SkinsNode object // (contains List of SkinNodes and List of SkinAdditionNodes) // and return a List of the SkinNodes. List metaInfSkinNodes = new ArrayList(); for (SkinsNode skinsNode : metaInfSkinsNodeList) { List skinNodes = skinsNode.getSkinNodes(); if (skinNodes != null) metaInfSkinNodes.addAll(skinNodes); } List sortedMetaInfSkinNodes = _sortSkinNodes(skinFactory, metaInfSkinNodes); for (SkinNode skinNode : sortedMetaInfSkinNodes) { _addSkinToFactory(skinFactory, skinNode, true); } // Add WEB-INF/trinidad-skins.xml skins to skin factory. (sorted first) if (_LOG.isFine()) _LOG.fine("Parse WEB-INF/trinidad-skins.xml files"); SkinsNode webInfSkinsNode = _getWebInfSkinsNode(context); if (webInfSkinsNode != null) { List webInfSkinNodes = webInfSkinsNode.getSkinNodes(); List sortedWebInfSkinNodes = _sortSkinNodes(skinFactory, webInfSkinNodes); // register skins found in webInfSkinNodes for (SkinNode skinNode : sortedWebInfSkinNodes) { _addSkinToFactory(skinFactory, skinNode, false); } } // register all the skin additions from META-INF trinidad-skins.xml and WEB-INF // trinidad-skins.xml that we have stored in the metaInfSkinsNodeList object and the // webInfSkinsNode object // skin-additions are additions to a skin, not extensions. They are used by // custom component developers that want to add a stylesheet for their components // to a particular skin, like the simple skin. FacesContext fContext = FacesContext.getCurrentInstance(); // register skin-additions from META-INF/trinidad-skins.xml files _registerMetaInfSkinAdditions(fContext, skinFactory, metaInfSkinsNodeList); // register skin-additions from WEB-INF/trinidad-skins.xml file if (webInfSkinsNode != null) { List skinAdditionNodeList = webInfSkinsNode.getSkinAdditionNodes(); _registerSkinAdditions(fContext, skinFactory, skinAdditionNodeList, false); } _registerTrinidadSkinsFromSkinResourceLoaderServices(context, skinFactory); } // this finds the trinidad-skins.xml files by calling findResource on any SkinResourceLoader // services. This is used by the DT to find trinidad-skins.xml files that are not in META-INF // or WEB-INF. See TRINIDAD-1914 private static void _registerTrinidadSkinsFromSkinResourceLoaderServices( ExternalContext context, SkinFactory skinFactory) { if (_LOG.isFine()) _LOG.fine("Parse SkinResourceLoader trinidad-skins.xml"); // register skins found in DT using the META-INF/services List urlProviders = ClassLoaderUtils.getServices( "org.apache.myfaces.trinidad.resource.SkinResourceLoader"); if (urlProviders != null && !urlProviders.isEmpty()) { List additionalSkins = _getAdditionalTrinidadSkins(context, urlProviders); // Go through each SkinsNode object // (contains List of SkinNodes and List of SkinAdditionNodes) // and return a List of the SkinNodes. List additionalSkinNodeList = new ArrayList(); for (SkinsNode skinsNode : additionalSkins) { additionalSkinNodeList.addAll(skinsNode.getSkinNodes()); } List sortedAdditionalSkinNodes = _sortSkinNodes(skinFactory, additionalSkinNodeList); for (SkinNode skinNode : sortedAdditionalSkinNodes) { if (_LOG.isFine()) _LOG.fine("Skin {0} with stylesheet {1}", new Object[]{skinNode.getId(), skinNode.getStyleSheetName()}); _addSkinToFactory(skinFactory, skinNode, false); } } } /** * Given the a List of SkinNodes, sort them so that the SkinNodes in such a way so that * when we register the skins we make sure that the 'base' skins are registered before * skins that extend them. * @param skinFactory * @param skinNodes * @return sorted List of SkinNodes */ private static List _sortSkinNodes( SkinFactory skinFactory, List skinNodes) { List sortedSkinNodes = new ArrayList(); List skinNodesAdded = new ArrayList(); List baseSkinIds = new ArrayList(); for (Iterator i = skinFactory.getSkinIds(); i.hasNext();) { baseSkinIds.add(i.next()); } // first, the skins that don't extend anything for (SkinNode skinNode : skinNodes) { String skinExtends = skinNode.getSkinExtends(); if (skinExtends == null) { sortedSkinNodes.add(skinNode); skinNodesAdded.add(skinNode.getId()); } } // second, the skins that extend another skin _sortSkinNodesWithExtensions(skinNodes, sortedSkinNodes, skinNodesAdded, baseSkinIds, 0); return sortedSkinNodes; } /** * This sorts SkinNodes that have their 'extends' value set, which means the skin * extends another skin. The order of our skin nodes matters in this case. We want the * base skin to be registered first. * @param skinNodes * @param sortedSkinNodes * @param skinNodesAdded * @param baseSkinIds */ private static void _sortSkinNodesWithExtensions( List skinNodes, List sortedSkinNodes, List skinNodesAdded, List baseSkinIds, int originalLeftOverListSize) { List leftOverList = new ArrayList(); for (SkinNode skinNode : skinNodes) { String skinExtends = skinNode.getSkinExtends(); if (skinExtends != null) { if (skinNodesAdded.contains(skinExtends) || baseSkinIds.contains(skinExtends)) { sortedSkinNodes.add(skinNode); skinNodesAdded.add(skinNode.getId()); } else { // left over, put in a left-over list leftOverList.add(skinNode); } } } if ((originalLeftOverListSize > 0) && (leftOverList.size() == originalLeftOverListSize)) { // Ok, we are left with skinNodes that cannot be registered because the skin they extend is // not in the skinNodesAdded List. The skin they extend might not exist at all, or // there is a circular dependency. // So..., just add these to the list. When we register these, they will cause a severe error // and the default base skin will be used. StringBuffer buffer = new StringBuffer(); for (SkinNode leftOverNode : leftOverList) { buffer.append("Skin with id: " + leftOverNode.getId() + " extends skin with id: " + leftOverNode.getSkinExtends() + "\n"); sortedSkinNodes.add(leftOverNode); skinNodesAdded.add(leftOverNode.getId()); } _LOG.warning("The following skins extend each other in a circular " + "fashion or the skin they extend does not exist.\n" + buffer.toString()); } else if (leftOverList.size() > 0) { _sortSkinNodesWithExtensions(leftOverList, sortedSkinNodes, skinNodesAdded, baseSkinIds, leftOverList.size()); } } /** * Given a skinNode, create a Skin object and * register the SkinExtension object with the skinFactory * @param skinFactory * @param skinNode */ private static void _addSkinToFactory( SkinFactory skinFactory, SkinNode skinNode, boolean isMetaInfFile) { // if the renderKitId is not specified, // set it to _RENDER_KIT_ID_CORE. String renderKitId = skinNode.getRenderKitId(); String id = skinNode.getId(); String family = skinNode.getFamily(); String styleSheetName = skinNode.getStyleSheetName(); String bundleName = skinNode.getBundleName(); String translationSourceExpression = skinNode.getTranslationSourceExpression(); SkinVersionNode skinVersionNode = skinNode.getSkinVersionNode(); SkinVersion skinVersion = _createSkinVersion(skinVersionNode); if (renderKitId == null) renderKitId = _RENDER_KIT_ID_DESKTOP; // figure out the base skin. Skin baseSkin = null; String skinExtends = skinNode.getSkinExtends(); if (skinExtends != null) baseSkin = skinFactory.getSkin(null, skinExtends); if (baseSkin == null) { baseSkin = _getDefaultBaseSkin(skinFactory, renderKitId); if (skinExtends != null) { _LOG.severe("UNABLE_LOCATE_BASE_SKIN", new String[]{skinExtends, id, family, renderKitId, baseSkin.getId()}); } } // Set the style sheet if (styleSheetName != null) { // If the styleSheetName is in the META-INF/trinidad-skins.xml file, then // we prepend META-INF to the styleSheetName if it doesn't begin with '/'. // This way we can find the file when we go to parse it later. if (isMetaInfFile) styleSheetName = _prependMetaInf(styleSheetName); } // If bundleName and translationSourceExpression are both set, then we // only use the bundleName. An error was already logged during trinidad-skins // parsing. Skin skin = null; // bundle-name takes precedence over translation-source if (bundleName != null) { skin = new SkinExtension(baseSkin, id, family, renderKitId, styleSheetName, bundleName, skinVersion); } else { ValueExpression translationSourceVE = null; if (translationSourceExpression != null) { translationSourceVE = _createTranslationSourceValueExpression(translationSourceExpression); } if (translationSourceVE != null) { skin = new SkinExtension(baseSkin, id, family, renderKitId, styleSheetName, translationSourceVE, skinVersion); } else { skin = new SkinExtension(baseSkin, id, family, renderKitId, styleSheetName, skinVersion); } } // Create a SkinExtension object and register skin with factory skinFactory.addSkin(id, skin); } private static ValueExpression _createTranslationSourceValueExpression( String translationSourceExpression) { if (translationSourceExpression != null) { translationSourceExpression = translationSourceExpression.trim(); return LazyValueExpression.createValueExpression(translationSourceExpression, Object.class); } else return null; } // Create a SkinVersion object from the SkinVersionNode object. private static SkinVersion _createSkinVersion(SkinVersionNode skinVersionNode) { if (skinVersionNode != null) { String name = skinVersionNode.getName(); boolean isDefault = skinVersionNode.isDefault(); if ("".equals(name) && !isDefault) return SkinVersion.EMPTY_SKIN_VERSION; else return new SkinVersion(name, isDefault); } else return SkinVersion.EMPTY_SKIN_VERSION; } /** * Get the WEB-INF/trinidad-skins.xml file, parse it, and return a List of SkinsNode objects. * @param context ServletContext used to getResourceAsStream * @return List of SkinNodes (skin elements) found in trinidad-skins.xml */ private static SkinsNode _getWebInfSkinsNode( ExternalContext context) { InputStream in = context.getResourceAsStream(_CONFIG_FILE); if (in != null) { SkinsNode webInfSkinsNode = _getSkinsNodeFromInputStream(null, null, in, _getDefaultManager(), _CONFIG_FILE); if (_LOG.isFine()) { for (SkinNode node : webInfSkinsNode.getSkinNodes()) { _LOG.fine("Skin {0} with stylesheet {1}", new Object[]{node.getId(), node.getStyleSheetName()}); } for (SkinAdditionNode node: webInfSkinsNode.getSkinAdditionNodes()) { _LOG.fine("SkinAddition {0} with stylesheet {1}", new Object[]{node.getSkinId(), node.getStyleSheetName()}); } } return webInfSkinsNode; } else { return null; } } /** * Get all the META-INF/trinidad-skins.xml files, parse them, and from each file we get * a SkinsNode object -- the information inside the <skins> element -- each skin * and each skin-addition. * @return Each SkinsNode object we get from each META-INF/trinidad-skins.xml file, * in a List. */ private static List _getMetaInfSkinsNodeList() { List allSkinsNodes = new ArrayList(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { Enumeration urls = loader.getResources(_META_INF_CONFIG_FILE); Set urlPaths = new HashSet(16); while (urls.hasMoreElements()) { URL url = urls.nextElement(); // if url matches one we've already processed, skip it boolean successfullyAdded = urlPaths.add(url.getPath()); // _processTrinidadSkinsURL logs the url we are processing _processTrinidadSkinsURL(allSkinsNodes, url, successfullyAdded); } } catch (IOException e) { _LOG.severe("ERR_LOADING_FILE", _META_INF_CONFIG_FILE); _LOG.severe(e); } return allSkinsNodes; } private static Skin _getDefaultBaseSkin( SkinFactory factory, String renderKitId) { String baseSkinId = (_RENDER_KIT_ID_PDA.equals(renderKitId)) ? _SIMPLE_PDA_SKIN_ID : _SIMPLE_DESKTOP_SKIN_ID; Skin baseSkin = factory.getSkin(null, baseSkinId); // It is an error if we were unable to find the base skin if (baseSkin == null) _LOG.severe(_UNKNOWN_BASE_SKIN_ERROR + baseSkinId); return baseSkin; } // register the META-INF skin additions. // It should not matter what order we process skin-additions since they should not // depend upon one another. // We sort them by style-sheet-name so the StyleSheetDocumentId will be the same regardless // of order. Portals are using the styleSheetDocumentId to determine if the producer's skin // matches the consumer's skin, and the order of the skin-additions should not change this. private static void _registerMetaInfSkinAdditions( FacesContext fContext, SkinFactory skinFactory, List metaInfSkinsNodeList) { List skinAdditionNodeList = new ArrayList(); for (SkinsNode skinsNode : metaInfSkinsNodeList) { skinAdditionNodeList.addAll(skinsNode.getSkinAdditionNodes()); } Collections.sort(skinAdditionNodeList); _registerSkinAdditions(fContext, skinFactory, skinAdditionNodeList, true); } /** * Get the skin id and other information from each SkinAdditionNode and * get the skin and register the SkinAddition with the skin * @param fContext * @param skinFactory * @param skinAdditionNodeList * @param isMetaInfFile true if the trinidad-skins.xml file is in the META-INF * directory. */ private static void _registerSkinAdditions( FacesContext fContext, SkinFactory skinFactory, List skinAdditionNodeList, boolean isMetaInfFile ) { for (SkinAdditionNode skinAdditionNode : skinAdditionNodeList) { String skinId = skinAdditionNode.getSkinId(); String styleSheetName = skinAdditionNode.getStyleSheetName(); String resourceBundleName = skinAdditionNode.getResourceBundleName(); String translationSourceExpression = skinAdditionNode.getTranslationSourceExpression(); Skin skin = skinFactory.getSkin(fContext, skinId); if (skin != null && ((styleSheetName != null) || (resourceBundleName != null) || (translationSourceExpression != null))) { // If the styleSheetName is in the META-INF/trinidad-skins.xml file, then // we prepend META-INF to the styleSheetName if it doesn't begin with '/'. // This way we can find the file when we go to parse it later. if (isMetaInfFile && (styleSheetName != null)) styleSheetName = _prependMetaInf(styleSheetName); SkinAddition addition = null; if (resourceBundleName != null) { // create SkinAddition with resourceBundleName addition = new SkinAddition(styleSheetName, resourceBundleName); } else { ValueExpression translationSourceVE = null; if (translationSourceExpression != null) { translationSourceVE = _createTranslationSourceValueExpression(translationSourceExpression); } if (translationSourceVE != null) { // Create a SkinAddition with translationSourceVE addition = new SkinAddition(styleSheetName, translationSourceVE); } else { // Create a SkinAddition with stylesheetName only addition = new SkinAddition(styleSheetName); } } skin.addSkinAddition(addition); } } } /** * Prepend META-INF to the styleSheetName if it doesn't begin with '/'. * @param styleSheetName * @return String styleSheetName or the styleSheetName prepended with META-INF/ */ private static String _prependMetaInf(String styleSheetName) { if (!(styleSheetName.startsWith("/"))) return _META_INF_DIR.concat(styleSheetName); else return styleSheetName; } // register skins found in DT using the META-INF/services private static List _getAdditionalTrinidadSkins( ExternalContext context, List providers) { Set urlPaths = new HashSet(16); List allSkinsNodes = new ArrayList(); for (SkinResourceLoader urlProvider : providers ) { Iterator urlIterator = urlProvider.findResources(context, _TRINIDAD_SKINS_XML); if (urlIterator != null) { try { while (urlIterator.hasNext()) { URL url = urlIterator.next(); // if url matches one we've already processed, skip it boolean successfullyAdded = urlPaths.add(url.getPath()); // _processTrinidadSkinsURL logs the url we are processing _processTrinidadSkinsURL(allSkinsNodes, url, successfullyAdded); } } catch (IOException e) { _LOG.severe("ERR_LOADING_FILE", _META_INF_CONFIG_FILE); _LOG.severe(e); } } } return allSkinsNodes; } private static void _processTrinidadSkinsURL( List allSkinsNodes, URL url, boolean successfullyAdded) throws IOException { if (!successfullyAdded) { if (_LOG.isFine()) { _LOG.fine("Skipping skin URL:{0} because it was already processed. " + "It was on the classpath more than once.", url); } // continue to the next url } else { if (_LOG.isFine()) _LOG.fine("Processing skin URL:{0}", url); URLConnection urlConnection = url.openConnection(); // prevent caching during DT where the source may change... if (Beans.isDesignTime()) { urlConnection.setUseCaches(false); } InputStream in = urlConnection.getInputStream(); try { // parse the config file and register the skin's additional stylesheets. if (in != null) { SkinsNode metaInfSkinsNode = _getSkinsNodeFromInputStream(null, null, in, _getDefaultManager(), url.toString()); if (metaInfSkinsNode != null) { // for debug only. if (_LOG.isFine()) { for (SkinNode node : metaInfSkinsNode.getSkinNodes()) _LOG.fine("Skin {0} with stylesheet {1}", new Object[]{node.getId(), node.getStyleSheetName()}); for (SkinAdditionNode node: metaInfSkinsNode.getSkinAdditionNodes()) _LOG.fine("SkinAddition {0} with stylesheet {1}", new Object[]{node.getSkinId(), node.getStyleSheetName()}); } allSkinsNodes.add(metaInfSkinsNode); } else { if(_LOG.isFine()) _LOG.fine("No skins found in the URL."); } } } catch (Exception e) { _LOG.warning("ERR_PARSING", url); _LOG.warning(e); } finally { in.close(); } } } private SkinUtils() {} // The default ParserManager static private ParserManager _sManager; // Constants // Prefix of LAf parsing package static private final String _LAF_PARSE_PACKAGE = "org.apache.myfaces.trinidadinternal.skin.parse."; static private final String _CONFIG_FILE = "/WEB-INF/trinidad-skins.xml"; static private final String _META_INF_CONFIG_FILE = "META-INF/trinidad-skins.xml"; static private final String _TRINIDAD_SKINS_XML = "trinidad-skins.xml"; static private final String _META_INF_DIR = "META-INF/"; static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SkinUtils.class); // Error messages private static final String _UNKNOWN_BASE_SKIN_ERROR = "Unable to locate base skin: "; static private final String _RENDER_KIT_ID_DESKTOP = "org.apache.myfaces.trinidad.desktop"; static private final String _RENDER_KIT_ID_PDA = "org.apache.myfaces.trinidad.pda"; static private final String _SIMPLE_PDA_SKIN_ID = "simple.pda"; static private final String _SIMPLE_DESKTOP_SKIN_ID = "simple.desktop"; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy