You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jw...@apache.org on 2013/10/17 17:25:59 UTC
svn commit: r1533115 [3/3] - in /myfaces/trinidad/trunk:
src/site/xdoc/devguide/
trinidad-api/src/main/java/org/apache/myfaces/trinidad/config/
trinidad-api/src/main/java/org/apache/myfaces/trinidad/skin/
trinidad-api/src/main/xrts/org/apache/myfaces/t...
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/CustomMetadataParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/CustomMetadataParser.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/CustomMetadataParser.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/CustomMetadataParser.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,90 @@
+/*
+ * 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.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.CustomMetadata;
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+/**
+ * This class is used when we parse the trinidad-skins.xml file and there is a 'metadata' element
+ * as a child of the 'skin' element. This is a collection of simple 'metadata' nodes, represented as Strings
+ * @see CustomMetadata
+ *
+ * @version $Name: $ ($Revision: $) $Date: $
+ */
+public class CustomMetadataParser extends BaseNodeParser
+ implements XMLConstants
+{
+ @Override
+ public void startElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ _skinMetadata = new HashMap<String, Object>();
+ }
+
+ @Override
+ public Object endElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName
+ ) throws SAXParseException
+ {
+ return new CustomMetadata(_skinMetadata);
+ }
+
+ @Override
+ public NodeParser startChildElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ return new StringParser();
+ }
+
+ @Override
+ public void addCompletedChild(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Object child
+ ) throws SAXParseException
+ {
+ _skinMetadata.put(localName, child);
+ }
+
+ private Map<String, Object> _skinMetadata;
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinAdditionParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinAdditionParser.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinAdditionParser.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinAdditionParser.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,192 @@
+/*
+ * 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.parse;
+
+import javax.el.ValueExpression;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.CustomMetadata;
+import org.apache.myfaces.trinidad.skin.SkinAddition;
+import org.apache.myfaces.trinidad.skin.SkinFeatures;
+import org.apache.myfaces.trinidadinternal.config.LazyValueExpression;
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+/**
+ * NodeParser for <skin-addition> node in trinidad-skins.xml
+ *
+ * @version $Name: $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinExtensionParser.java#0 $) $Date: 10-nov-2005.18:50:44 $
+ * @todo ELIMINATE NAMESPACE
+ */
+public class SkinAdditionParser extends BaseNodeParser
+ implements XMLConstants
+{
+ @Override
+ public void startElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ }
+
+ @Override
+ public Object endElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName
+ ) throws SAXParseException
+ {
+
+ // id is required for a SkinAddition. log a severe error if it is null.
+ if (_skinId == null)
+ _LOG.severe("REQUIRED_ELEMENT_SKINID_NOT_FOUND");
+
+ if ((_resourceBundleName != null) && (_translationSourceExpression != null))
+ {
+ _LOG.severe("BOTH_BUNDLENAME_TRANSLATIONSOURCE_SET");
+ _translationSourceExpression = null;
+ }
+
+ if (_translationSourceExpression != null &&
+ !(_translationSourceExpression.startsWith("#{") &&
+ _translationSourceExpression.endsWith("}")))
+ {
+ _LOG.severe("TRANSLATION_SOURCE_NOT_EL");
+ _translationSourceExpression = null;
+ }
+
+ Object isMetaInf = context.getProperty(SKIN_NAMESPACE, META_INF);
+
+ if (isMetaInf != null && _styleSheetName != null
+ && Boolean.parseBoolean(isMetaInf.toString()) && !(_styleSheetName.startsWith("/")))
+ _styleSheetName = META_INF_DIR.concat(_styleSheetName);
+
+ SkinFeatures features = _skinFeatures;
+
+ SkinAddition addition = null;
+ if (_styleSheetName != null
+ || _resourceBundleName != null
+ || _translationSourceExpression != null)
+ {
+ if (_resourceBundleName != null)
+ {
+ // create SkinAddition with resourceBundleName
+ addition = new SkinAddition.Builder().skinId(_skinId).styleSheetName(_styleSheetName)
+ .resourceBundleName(_resourceBundleName).features(features).build();
+ }
+ else
+ {
+ ValueExpression translationSourceVE = null;
+
+ if (_translationSourceExpression != null)
+ {
+ translationSourceVE = LazyValueExpression.createValueExpression(_translationSourceExpression.trim(), Object.class);
+ }
+
+ if (translationSourceVE != null)
+ {
+ // Create a SkinAddition with translationSourceVE
+ addition = new SkinAddition.Builder().skinId(_skinId).styleSheetName(_styleSheetName)
+ .translationSource(translationSourceVE).features(features).build();
+ }
+ else
+ {
+ // Create a SkinAddition with stylesheetName only
+ addition = new SkinAddition.Builder().skinId(_skinId).styleSheetName(_styleSheetName).features(features).build();
+ }
+ }
+ }
+ else if (features != null)
+ {
+ addition = new SkinAddition.Builder().skinId(_skinId).features(features).build();
+ }
+
+ return addition;
+ }
+
+ @Override
+ public NodeParser startChildElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+
+ if ("skin-id".equals(localName) ||
+ "style-sheet-name".equals(localName) ||
+ "bundle-name".equals(localName) ||
+ "translation-source".equals(localName))
+
+ {
+ return new StringParser();
+ }
+ else if ("features".equals(localName))
+ {
+ return context.getParser(SkinFeatures.class, namespaceURI, localName);
+ }
+ else if ("metadata".equals(localName))
+ {
+ return context.getParser(CustomMetadata.class, namespaceURI, localName);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void addCompletedChild(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Object child
+ ) throws SAXParseException
+ {
+
+ if ("skin-id".equals(localName))
+ _skinId = (String) child;
+ else if ("style-sheet-name".equals(localName))
+ _styleSheetName = (String) child;
+ else if ("bundle-name".equals(localName))
+ _resourceBundleName = (String) child;
+ else if ("translation-source".equals(localName))
+ _translationSourceExpression = (String) child;
+ else if ("features".equals(localName))
+ {
+ _skinFeatures = (SkinFeatures) child;
+ }
+ }
+
+ private String _skinId;
+ private String _styleSheetName;
+ private String _resourceBundleName;
+ private String _translationSourceExpression;
+ private SkinFeatures _skinFeatures;
+
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(SkinAdditionParser.class);
+
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinFeaturesParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinFeaturesParser.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinFeaturesParser.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinFeaturesParser.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,113 @@
+/*
+ * 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.parse;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+import org.apache.myfaces.trinidad.skin.SkinFeatures;
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+/**
+ * This class is used when we parse the trinidad-skins.xml file and there is a 'features' element
+ * as a child of the 'skin' element. This is a collection of simple 'feature' nodes, represented as Strings
+ * @see SkinFeatures
+ *
+ * @version $Name: $ ($Revision: $) $Date: $
+ */
+public class SkinFeaturesParser extends BaseNodeParser
+ implements XMLConstants
+{
+ @Override
+ public void startElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ _skinFeatures = new HashMap<String, String>();
+ }
+
+ @Override
+ public Object endElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName
+ ) throws SAXParseException
+ {
+
+ return new SkinFeatures(_skinFeatures);
+ }
+
+ @Override
+ public NodeParser startChildElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ if("feature".equals(localName))
+ {
+ _currentAttributes = attrs;
+ return new StringParser();
+ }
+ else
+ { //Clear it out if we are not processing a feature currently
+ _currentAttributes = null;
+ }
+ return null;
+ }
+
+ @Override
+ public void addCompletedChild(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Object child
+ ) throws SAXParseException
+ {
+
+ if ("feature".equals(localName) && _currentAttributes != null)
+ {
+ String name = _currentAttributes.getValue("name");
+ if(name != null && String.class.isInstance(child))
+ {
+ _skinFeatures.put(name, (String)child);
+ }
+ }
+ }
+
+ private Map<String, String> _skinFeatures;
+ private Attributes _currentAttributes;
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(SkinFeaturesParser.class);
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinMetadataParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinMetadataParser.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinMetadataParser.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinMetadataParser.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,199 @@
+/*
+ * 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.parse;
+
+import javax.el.ValueExpression;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.CustomMetadata;
+import org.apache.myfaces.trinidad.skin.SkinFeatures;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+import org.apache.myfaces.trinidadinternal.config.LazyValueExpression;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlConstants;
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+/**
+ * NodeParser for <skin> node in trinidad-skins.xml
+ *
+ * @version $Name: $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinExtensionParser.java#0 $) $Date: 10-nov-2005.18:50:44 $
+ * @todo ELIMINATE NAMESPACE
+ */
+public class SkinMetadataParser extends BaseNodeParser
+ implements XMLConstants
+{
+ @Override
+ public void startElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ _namespace = namespaceURI;
+ }
+
+ @Override
+ public Object endElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName
+ ) throws SAXParseException
+ {
+
+ // id and family are required. log a severe error if they are null.
+ if (_id == null)
+ {
+ _LOG.severe("REQUIRED_ELEMENT_ID_NOT_FOUND");
+ throw new NullPointerException(_LOG.getMessage("NULL_ID"));
+ }
+
+ if (_family == null)
+ {
+ _LOG.severe("REQURIED_ELEMENT_FAMILY_NOT_FOUND");
+ throw new NullPointerException(_LOG.getMessage("NULL_FAMILY"));
+ }
+
+ if ((_bundleName != null) && (_translationSourceExpression != null))
+ {
+ _LOG.severe("BOTH_BUNDLENAME_TRANSLATIONSOURCE_SET");
+ _translationSourceExpression = null;
+ }
+
+ if (_translationSourceExpression != null &&
+ !(_translationSourceExpression.startsWith("#{") &&
+ _translationSourceExpression.endsWith("}")))
+ {
+ _LOG.severe("TRANSLATION_SOURCE_NOT_EL");
+ _translationSourceExpression = null;
+ }
+
+ Object isMetaInf = context.getProperty(SKIN_NAMESPACE, META_INF);
+
+ if (isMetaInf != null && _styleSheetName != null
+ && Boolean.parseBoolean(isMetaInf.toString()) && !(_styleSheetName.startsWith("/")))
+ _styleSheetName = META_INF_DIR.concat(_styleSheetName);
+
+ ValueExpression translationSource = null;
+
+ if (_translationSourceExpression != null)
+ translationSource = LazyValueExpression.createValueExpression(_translationSourceExpression, Object.class);
+
+ // here since we are reading from trinidad-skins.xml we have to assert that id and
+ // family is set.
+ // creation of SkinNode threw NullPointerException if Id or family was not provided
+ // at this point. Since we use SkinMetadata for querying skins we cannot assert that
+ // id and family should be set. So we do this check here in the parser.
+ return new SkinMetadata.Builder().id(_id).family(_family).renderKitId(SkinMetadata.RenderKitId.fromId(_renderKitId))
+ .baseSkinId(_extends).styleSheetName(_styleSheetName).resourceBundleName(_bundleName)
+ .translationSource(translationSource).version(_skinVersionNode)
+ .features(_skinFeaturesNode).metadata(_skinMetadataNode).build();
+ }
+
+ @Override
+ public NodeParser startChildElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ if (!namespaceURI.equals(_namespace))
+ return null;
+
+ if ("id".equals(localName) ||
+ "family".equals(localName) ||
+ "render-kit-id".equals(localName) ||
+ "style-sheet-name".equals(localName) ||
+ "bundle-name".equals(localName) ||
+ "translation-source".equals(localName) ||
+ "extends".equals(localName))
+
+ {
+ return new StringParser();
+ }
+ else if ("version".equals(localName))
+ {
+ return context.getParser(SkinVersion.class, namespaceURI, localName);
+ }
+ else if ("features".equals(localName))
+ {
+ return context.getParser(SkinFeatures.class, namespaceURI, localName);
+ }
+ else if ("metadata".equals(localName))
+ {
+ return context.getParser(CustomMetadata.class, namespaceURI, localName);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void addCompletedChild(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Object child
+ ) throws SAXParseException
+ {
+
+ if ("id".equals(localName))
+ _id = (String) child;
+ else if ("family".equals(localName))
+ _family = (String) child;
+ else if ("render-kit-id".equals(localName))
+ _renderKitId = (String) child;
+ else if ("style-sheet-name".equals(localName))
+ _styleSheetName = (String) child;
+ else if ("bundle-name".equals(localName))
+ _bundleName = (String) child;
+ else if ("translation-source".equals(localName))
+ _translationSourceExpression = (String) child;
+ else if ("extends".equals(localName))
+ _extends = (String) child;
+ else if ((child instanceof SkinVersion))
+ _skinVersionNode = ((SkinVersion)child);
+ else if ((child instanceof SkinFeatures))
+ _skinFeaturesNode = ((SkinFeatures)child);
+ else if ((child instanceof CustomMetadata))
+ _skinMetadataNode = ((CustomMetadata)child);
+ }
+
+ private String _namespace;
+ private String _id;
+ private String _family;
+ private String _styleSheetName;
+ private String _renderKitId;
+ private String _bundleName;
+ private String _translationSourceExpression;
+ private String _extends;
+ private SkinVersion _skinVersionNode;
+ private SkinFeatures _skinFeaturesNode;
+ private CustomMetadata _skinMetadataNode;
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(SkinMetadataParser.class);
+
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinVersionParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinVersionParser.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinVersionParser.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinVersionParser.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,111 @@
+/*
+ * 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.parse;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+
+/**
+ * This class is used when we parse the trinidad-skins.xml file and there is a 'version' element
+ * as a child of the 'skin' element. A 'version' has both a 'name' (required) and
+ * a 'default' (optional) element. After parsing, a SkinVersion object is created and attached
+ * to the Skin object.
+ * @see SkinVersion
+ * @see org.apache.myfaces.trinidadinternal.skin.SkinUtils
+ * @see org.apache.myfaces.trinidad.skin.SkinVersion
+ */
+public class SkinVersionParser extends BaseNodeParser
+ implements XMLConstants
+{
+ @Override
+ public void startElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+ }
+
+ @Override
+ public Object endElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName
+ ) throws SAXParseException
+ {
+ // allow no name in version.
+ if (_name == null)
+ _name = "";
+
+ return new SkinVersion(_name, "true".equals(_default));
+ }
+
+ @Override
+ public NodeParser startChildElement(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Attributes attrs
+ ) throws SAXParseException
+ {
+
+ if ("name".equals(localName) ||
+ "default".equals(localName))
+
+ {
+ return new StringParser();
+ }
+
+ return null;
+ }
+
+ @Override
+ public void addCompletedChild(
+ ParseContext context,
+ String namespaceURI,
+ String localName,
+ Object child
+ ) throws SAXParseException
+ {
+
+ if ("name".equals(localName))
+ _name = (String) child;
+ else if ("default".equals(localName))
+ {
+ _default = (String) child;
+ // <default/> means true
+ if (_default == null || "".equals(_default))
+ _default = "true";
+ }
+ }
+
+ private String _name;
+ private String _default;
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(SkinVersionParser.class);
+}
\ No newline at end of file
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNode.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNode.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNode.java Thu Oct 17 15:25:57 2013
@@ -18,8 +18,13 @@
*/
package org.apache.myfaces.trinidadinternal.skin.parse;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import org.apache.myfaces.trinidad.skin.SkinAddition;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+
/**
* Object which represents the skin and skin-addition nodes in trinidad-skins.xml.
*
@@ -28,11 +33,11 @@ import java.util.List;
public class SkinsNode
{
/**
- *
+ *
*/
public SkinsNode(
- List<SkinNode> skinNodes,
- List<SkinAdditionNode> skinAdditionNodes)
+ List<SkinMetadata> skinNodes,
+ List<SkinAddition> skinAdditionNodes)
{
_skinAdditionNodes = skinAdditionNodes;
_skinNodes = skinNodes;
@@ -40,19 +45,19 @@ public class SkinsNode
/**
*/
- public List<SkinAdditionNode> getSkinAdditionNodes()
+ public List<SkinAddition> getSkinAdditionNodes()
{
return _skinAdditionNodes;
}
/**
- *
+ *
*/
- public List<SkinNode> getSkinNodes()
+ public List<SkinMetadata> getSkinNodes()
{
return _skinNodes;
}
-
- private List<SkinAdditionNode> _skinAdditionNodes;
- private List<SkinNode> _skinNodes;
+
+ private List<SkinAddition> _skinAdditionNodes;
+ private List<SkinMetadata> _skinNodes;
}
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNodeParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNodeParser.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNodeParser.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/SkinsNodeParser.java Thu Oct 17 15:25:57 2013
@@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.List;
+import org.apache.myfaces.trinidad.skin.SkinAddition;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;
@@ -46,9 +48,9 @@ public class SkinsNodeParser extends Bas
) throws SAXParseException
{
if ("skin-addition".equals(localName))
- return context.getParser(SkinAdditionNode.class, namespaceURI, localName);
+ return context.getParser(SkinAddition.class, namespaceURI, localName);
else
- return context.getParser(SkinNode.class, namespaceURI, localName);
+ return context.getParser(SkinMetadata.class, namespaceURI, localName);
}
@Override
@@ -59,14 +61,16 @@ public class SkinsNodeParser extends Bas
Object child
) throws SAXParseException
{
- assert ((child == null) ||
- (child instanceof SkinNode) ||
- (child instanceof SkinAdditionNode));
-
- if ((child instanceof SkinAdditionNode))
- _skinAdditions.add((SkinAdditionNode)child);
- else
- _skins.add((SkinNode)child);
+ assert ((child == null) ||
+ (child instanceof SkinMetadata) ||
+ (child instanceof SkinAddition));
+
+ // we should not add a child which is null
+ // so use both instance checks
+ if (child instanceof SkinAddition)
+ _skinAdditions.add((SkinAddition)child);
+ else if (child instanceof SkinMetadata)
+ _skins.add((SkinMetadata)child);
}
@Override
@@ -80,7 +84,7 @@ public class SkinsNodeParser extends Bas
_skinAdditions);
}
- private List<SkinNode> _skins = new ArrayList<SkinNode>();
- private List<SkinAdditionNode> _skinAdditions = new ArrayList<SkinAdditionNode>();
-
+ private List<SkinMetadata> _skins = new ArrayList<SkinMetadata>();
+ private List<SkinAddition> _skinAdditions = new ArrayList<SkinAddition>();
+
}
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/XMLConstants.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/XMLConstants.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/XMLConstants.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/parse/XMLConstants.java Thu Oct 17 15:25:57 2013
@@ -29,4 +29,7 @@ public interface XMLConstants
"http://myfaces.apache.org/trinidad/skin";
public static final String NULL_NAME = "null";
+ public static final String META_INF = "meta-inf";
+ public static final String META_INF_DIR = "META-INF/";
+
}
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationService.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationService.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationService.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationService.java Thu Oct 17 15:25:57 2013
@@ -33,7 +33,8 @@ import javax.faces.context.ResponseWrite
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.render.InternalView;
import org.apache.myfaces.trinidad.skin.Skin;
-import org.apache.myfaces.trinidad.skin.SkinFactory;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
import org.apache.myfaces.trinidad.util.Enums;
import org.apache.myfaces.trinidadinternal.skin.pregen.config.InvalidConfigException;
import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig;
@@ -137,11 +138,11 @@ public class SkinPregenerationService ex
ExternalContext external = context.getExternalContext();
return external.getRequestParameterMap().get(_SKIN_ID_REQUEST_PARAM);
}
-
+
private static Skin _getSkin(FacesContext context, String skinId)
{
- SkinFactory factory = SkinFactory.getFactory();
- return factory.getSkin(context, skinId);
+ SkinProvider provider = SkinProvider.getCurrentInstance(context.getExternalContext());
+ return provider.getSkin(context, new SkinMetadata.Builder().id(skinId).build());
}
private static void _pregenFailed(FacesContext context, Exception e)
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/ExternalSkinProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/ExternalSkinProvider.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/ExternalSkinProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/ExternalSkinProvider.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,118 @@
+/*
+ * 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.provider;
+
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinFactory;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl;
+
+/**
+ * ExternalSkinProvider serves to maintain backward compatibility with legacy SkinFactory users.
+ * Before we introduced SkinProvider SPI, users can register skins in the lifecycle of
+ * the Configurator using reloadSkins API.
+ * With SkinProvider SPI, this method of registering skins is deprecated. This provider is used to
+ * support the existing users who use SkinFactory to register / reload skins. This provider manages
+ * the skins added to the SkinFactory and provides methods to perform the SkinFactory operations.
+ *
+ * Essentially SkinFactory methods will call this provider for methods like addSkin, getSkinIds etc
+ * which interact with the skins added to the factory.
+ */
+public class ExternalSkinProvider extends BaseSkinProvider
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Skin loadAvailableSkin(FacesContext context, SkinMetadata skinMetadata)
+ {
+ // this case will never rise with this provider.
+ // any skin supported by this provider is added using
+ // addSkins API. So the parent class will have all the skins
+ // supported by this provider and there is no need to load it
+ return null;
+ }
+
+ /**
+ * called from SkinFactory to reload the skins that are registered with SkinFactory
+ * With this provider, the skins registered with SkinFactory are managed in this provider
+ */
+ public final void reload()
+ {
+ synchronized (this)
+ {
+ FacesContext fc = FacesContext.getCurrentInstance();
+
+ if (fc != null)
+ {
+ SkinFactory factory = SkinFactory.getFactory();
+ _LOG.fine("Reloading skins begin");
+
+ // backup the old skins to help in recovery if need be
+ Map<SkinMetadata, Skin> oldSkins = getSkins();
+ initSkins();
+
+ try
+ {
+ // give chance for configurator services to attach any skins that was not defined trinidad-skins.xml
+ GlobalConfiguratorImpl.getInstance().reloadSkins(fc.getExternalContext(), factory);
+ }
+ catch (Exception e)
+ {
+ _LOG.severe("SKIN_RELOAD_FAILURE", e);
+ setSkins(oldSkins);
+ }
+ finally
+ {
+ _LOG.fine("Reloading skins complete");
+ }
+ }
+ }
+ }
+
+ /**
+ * static factory method to get hold of a ExternalSkinProvider object
+ * This can be used for easy creation of Skin object without having to
+ * implement the abstract class
+ * @param ec
+ * @return
+ */
+ public static ExternalSkinProvider getCurrentInstance(ExternalContext ec)
+ {
+ if (ec == null)
+ throw new NullPointerException("ExternalContext is passed as null");
+
+ ExternalSkinProvider esp = (ExternalSkinProvider) ec.getApplicationMap().get(EXTERNAL_SKIN_PROVIDER_KEY);
+ return esp;
+ }
+
+ /**
+ * Key for the ExternalSkinProvider stored in ExternalContext
+ */
+ public static final String EXTERNAL_SKIN_PROVIDER_KEY =
+ "org.apache.myfaces.trinidad.skin.EXTERNAL_SKIN_PROVIDER_INSTANCE";
+
+ private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(ExternalSkinProvider.class);
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/SkinProviderRegistry.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,514 @@
+/*
+ * 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.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants;
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+
+/**
+ * Internal implementation of SkinProvider which is exposed using SkinProvider.getCurrentInstance()
+ * This class collates all SkinProvider SPIs, Trinidad SkinProviders
+ * and SkinFactory to return the best match for a Skin requested
+ * This class reads all registered SPIs using org.apache.myfaces.trinidad.skin.SkinProvider
+ *<p/>
+ * Instance of this class is created and put into the ExternalContext during
+ * bootstrap in GlobalConfiguratorImpl and retrieved in the static factory inside SkinProvider
+ * <p/>
+ */
+public class SkinProviderRegistry extends SkinProvider
+{
+
+ public SkinProviderRegistry()
+ {
+ List<SkinProvider> services = ClassLoaderUtils.getServices(SkinProvider.class.getName());
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding providers from registered SPIs... " + services.size());
+
+ List<SkinProvider> providers = new ArrayList<SkinProvider>(services.size() + 2);
+ providers.addAll(services);
+
+ // add internal skin providers at the end
+ // this is to give the other SPIs a chance before the internal skin providers
+ if (_LOG.isFine())
+ _LOG.fine("Adding TrinidadSkinProvider... ");
+
+ providers.add(new TrinidadSkinProvider());
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding TrinidadBaseSkinProvider... ");
+
+ providers.add(new TrinidadBaseSkinProvider());
+
+ if (_LOG.isFine())
+ _LOG.fine("Adding ExternalSkinProvider... ");
+
+ providers.add(SkinUtils.getExternalSkinProvider(null));
+
+ _providers = Collections.unmodifiableList(providers);
+ }
+
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(FacesContext context)
+ {
+ Collection<SkinMetadata> metadata = new ArrayList<SkinMetadata>();
+
+ for (SkinProvider provider : _providers)
+ metadata.addAll(provider.getSkinMetadata(context));
+
+ return Collections.unmodifiableCollection(metadata);
+ }
+
+ /**
+ * @param context
+ * @param skinMetadata search criteria object containing the information of skin to be queried
+ * id, family, renderKit, version are the information used from skin metadata
+ * to perform search for the skin requested.
+ * Other fields do not participate in the search.
+ * @return matching skin for the search criteria passed,
+ * if none found, return the simple skin for the renderKit in search criteria
+ * if renderKit not specified in search criteria, skinMetadata automatically assumes it as
+ * SkinMetadata.RenderKitId.DESKTOP
+ */
+ @Override
+ public Skin getSkin(FacesContext context, SkinMetadata skinMetadata)
+ {
+ _handleCircularDependency(context, skinMetadata);
+
+ List<Skin> matchingSkins = new ArrayList<Skin>();
+ Skin matchingSkin = null;
+
+ if (_LOG.isFine())
+ _LOG.fine("Skin request for metadata: " + skinMetadata);
+
+ for (SkinProvider provider : _providers)
+ {
+ matchingSkin = provider.getSkin(context, skinMetadata);
+
+ if (matchingSkin != null)
+ {
+ // log which provider got skin etc
+ if (_LOG.isFine())
+ _LOG.fine("Skin obtained for metadata: " + skinMetadata + " from provider: " + provider);
+
+ matchingSkins.add(matchingSkin);
+ }
+ }
+
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Skin obtained for metadata: " + skinMetadata + " from Skinfactory");
+
+ matchingSkins.add(matchingSkin);
+ }
+
+ if (_LOG.isFine())
+ _LOG.fine("Matches obtained for " + skinMetadata + ": " + matchingSkins.size());
+
+ // now we are done with asking all skin providers
+ // ensure that the matching skins returned are indeed matching the search criteria
+ // onus is on SkinProviderRegistry to serve the skin requested, even if a SkinProvider
+ // returns a wrong skin.
+
+ // filter the results obtained from skin providers based on id, family and renderKit
+ // filtering on version is more complicated and taken up subsequently
+ matchingSkins = _filterSkins(matchingSkins, skinMetadata);
+
+ if (matchingSkins.isEmpty())
+ {
+ if (_LOG.isFine())
+ _LOG.fine("NO MATCH. Will return a simple skin or null for skin metadata: " + skinMetadata);
+
+ assert (skinMetadata.getRenderKitId() != null);
+ // if renderKit is available return the simple skin for that renderKit
+ // skinMetadata.getRenderKitId() can never be null, default renderKit will always be DESKTOP
+ return _returnSkin(context, skinMetadata, _getSimpleSkinForRenderKit(context, skinMetadata.getRenderKitId()));
+ }
+
+
+ // we have at least one match now
+ // if we have only one match
+ // return that skin
+ if (matchingSkins.size() == 1)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning ONLY match for skin metadata: " + skinMetadata);
+
+ return _returnSkin(context, skinMetadata, matchingSkins.get(0));
+ }
+
+ // at this point we have more than one matches for the search criteria passed
+ // so, extract the best match based on version
+ return _versionFilter(context, skinMetadata, matchingSkins);
+ }
+
+ /**
+ * ensure sanity in the list of matches received by filtering the skins based on id, family and renderKit
+ * @param skins
+ * @param metadata
+ * @return
+ */
+ private List<Skin> _filterSkins(List<Skin> skins, SkinMetadata metadata)
+ {
+ if (skins == null || skins.isEmpty() || metadata == null)
+ return Collections.emptyList();
+
+ List<Skin> filterList = _idFilter(skins, metadata.getId());
+
+ // if the id based filtering resulted in only match then return that
+ // provided id was mentioned in search criteria
+ if (filterList.size() == 1 && metadata.getId() != null)
+ {
+ return filterList;
+ }
+
+ // if more than one match for id or if id is not specified, then filter by family
+ filterList = _familyFilter(filterList, metadata.getFamily());
+
+ // if the family based filtering resulted in only match then return that
+ // provided family was mentioned in search criteria
+ if (filterList.size() == 1 && metadata.getFamily() != null)
+ {
+ return filterList;
+ }
+
+ // if family based filtering resulted in multiple matches, or if family and id are not specified,
+ // proceed with renderKit based filtering.
+ filterList = _renderKitFilter(filterList, metadata.getRenderKitId());
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin id, if mentioned. Otherwise return the list as is
+ * @param skins
+ * @param id
+ * @return
+ */
+ private List<Skin> _idFilter(List<Skin> skins, String id)
+ {
+ if (id == null || id.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (id.equals(skin.getId()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin family, if mentioned. Otherwise return the list as is
+ * @param skins
+ * @param family
+ * @return
+ */
+ private List<Skin> _familyFilter(List<Skin> skins, String family)
+ {
+ if (family == null || family.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (family.equals(skin.getFamily()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on skin renderkit id, if mentioned. Otherwise return the list as is
+ * @param skins
+ * @param renderKitId
+ * @return
+ */
+ private List<Skin> _renderKitFilter(List<Skin> skins, String renderKitId)
+ {
+ if (renderKitId == null || renderKitId.isEmpty())
+ return skins;
+
+ List<Skin> filterList = new ArrayList<Skin>(skins.size());
+
+ for (Skin skin : skins)
+ if (renderKitId.equals(skin.getRenderKitId()))
+ filterList.add(skin);
+
+ return filterList;
+ }
+
+ /**
+ * filter based on version
+ * if version is mentioned try to return exact match
+ * else if version is not mentioned or version is default try to return default skin
+ * else try to return leaf skin
+ * else return first match
+ * @param context
+ * @param searchCriteria
+ * @param matchingSkins
+ * @return
+ */
+ private Skin _versionFilter(FacesContext context, SkinMetadata searchCriteria, List<Skin> matchingSkins)
+ {
+ SkinVersion version = searchCriteria.getVersion();
+ Skin matchingSkin;
+ // we can now find the best match based on version
+ // now that there is a version mentioned and skins matching is > 1
+ // look for exact name match
+ matchingSkin = _findSkinForVersionName(matchingSkins, version);
+
+ // if we found exact match in version, return it.
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning exact version match.");
+
+ return _returnSkin(context, searchCriteria, matchingSkin);
+ }
+
+ // either user is looking for default version or did not find the version requested
+ // try to find a default skin
+ matchingSkin = _findSkinWithDefaultVersion(matchingSkins);
+
+ // if we found the default version skin, return it.
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("returning DEFAULT version match.");
+ return _returnSkin(context, searchCriteria, matchingSkin);
+ }
+
+ // the version that user asked for is not available
+ // so find leaf skin
+ matchingSkin = _findLeafSkin(matchingSkins);
+
+ // if we found a leaf skin return that
+ if (matchingSkin != null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("return LEAF skin or one of the matches.");
+
+ return _returnSkin(context, searchCriteria, matchingSkin);
+ }
+
+ // we failed to find any better result for the given version, so return first match
+ if (_LOG.isFine())
+ _LOG.fine("nothing worked so return first match.");
+
+ return _returnSkin(context, searchCriteria, matchingSkins.get(0));
+ }
+
+ private Skin _returnSkin(FacesContext context, SkinMetadata skinMetadata, Skin skin)
+ {
+ // nothing to do if context is not available
+ if (context == null)
+ return skin;
+
+ Object o = context.getAttributes().get(_SKIN_PROVIDER_CONTEXT);
+ List<SkinMetadata> requesters = null;
+
+ if (o == null)
+ {
+ requesters = new ArrayList<SkinMetadata>();
+ context.getAttributes().put(_SKIN_PROVIDER_CONTEXT, requesters);
+ }
+ else
+ requesters = (List) o;
+
+ // remove the skinMetadata
+ requesters.remove(skinMetadata);
+
+ if (_LOG.isFiner())
+ {
+ _LOG.finer("Removing " + skinMetadata + " from context");
+ _LOG.finer("Context now is " + requesters);
+ }
+
+ return skin;
+ }
+
+ /**
+ * find a skin with version passed
+ * @param skins
+ * @param version
+ * @return
+ */
+ private Skin _findSkinForVersionName(Collection<Skin> skins, SkinVersion version)
+ {
+ if (version == null)
+ throw new IllegalArgumentException("skin version cannot be null");
+
+ if (version.getName() == null || version.getName().isEmpty())
+ return null;
+
+ for (Skin skin : skins)
+ {
+ // metadata cannot be null and also version inside it cannot be null
+ if (version.getName().equals(skin.getVersion().getName()))
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found version match skin: " + skin);
+
+ return skin;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Latest skin is the one which is last in the family hierarchy
+ * eg: fusion-v1 -> fusion-v2 -> fusion-v3
+ * Among this fusion-v3 is the latest. So we look for a skin that is
+ * not extended by any other skin in the family.
+ * @param skins
+ * @return
+ */
+ private Skin _findLeafSkin(Collection<Skin> skins)
+ {
+ List<Skin> leafSkins = new ArrayList<Skin>();
+ List<String> parentIds = new ArrayList<String>();
+
+ // collect parents skins among the list
+ for (Skin metadata : skins)
+ {
+ Skin baseSkin = metadata.getBaseSkin();
+ if (baseSkin != null)
+ {
+ String parentId = baseSkin.getId();
+ if (parentId != null)
+ parentIds.add(parentId);
+ }
+ }
+
+ // find leaf skins, which is not in parent list
+ for (Skin skin : skins)
+ {
+ String skinId = skin.getId();
+ if (skinId != null && !parentIds.contains(skinId))
+ {
+ leafSkins.add(skin);
+ }
+ }
+
+ // if there are no leaves, return null
+ // this is a rare case, almost impossible since there will be
+ // at least one skin which is not parent of another
+ // but let us cover the corner case if any
+ if (leafSkins.isEmpty())
+ return null;
+
+ // if there is one leaf skin return that
+ // if there are many, return the last one among the leaves
+ return leafSkins.get(leafSkins.size() - 1);
+ }
+
+ /**
+ * find a skin that has its SkinVersion set to 'default', if it exists.
+ * @param matchingSkinList A list of Skins that we will look through to find the 'default'.
+ * @return Skin with SkinVersion isDefault true, otherwise, null.
+ */
+ private Skin _findSkinWithDefaultVersion(Collection<Skin> matchingSkinList)
+ {
+ for (Skin skin : matchingSkinList)
+ {
+ SkinVersion skinVersion = skin.getVersion();
+
+ if (skinVersion != null && skinVersion.isDefault())
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Found default skin: " + skin);
+
+ return skin;
+ }
+ }
+
+ return null;
+ }
+
+ private void _handleCircularDependency(FacesContext context, SkinMetadata skinMetadata)
+ {
+ // nothing to do if context is not available
+ if (context == null)
+ return;
+
+ Object o = context.getAttributes().get(_SKIN_PROVIDER_CONTEXT);
+ List<SkinMetadata> requesters = null;
+
+ if (o == null)
+ {
+ requesters = new ArrayList<SkinMetadata>();
+ context.getAttributes().put(_SKIN_PROVIDER_CONTEXT, requesters);
+ }
+ else
+ requesters = (List) o;
+
+ if (requesters.contains(skinMetadata))
+ {
+ String message = "Circlular dependency detected whille loading skin: " + skinMetadata
+ + ". Requesters are: " + requesters;
+ if (_LOG.isSevere())
+ _LOG.severe(message);
+
+ throw new IllegalStateException(message);
+ }
+
+ // add the currently requested metadata into list
+ requesters.add(skinMetadata);
+
+ if (_LOG.isFiner())
+ {
+ _LOG.finer("Adding " + skinMetadata + " to context");
+ _LOG.finer("Context now is " + requesters);
+ }
+ }
+
+ private Skin _getSimpleSkinForRenderKit(FacesContext context, String renderKitId)
+ {
+ if (renderKitId != null && renderKitId.equals(TrinidadRenderingConstants.APACHE_TRINIDAD_PORTLET))
+ return getSkin(context, new SkinMetadata.Builder().id(TrinidadRenderingConstants.SIMPLE_PORTLET_ID).build());
+
+ if (renderKitId != null && renderKitId.equals(TrinidadRenderingConstants.APACHE_TRINIDAD_PDA))
+ return getSkin(context, new SkinMetadata.Builder().id(TrinidadRenderingConstants.SIMPLE_PDA_ID).build());
+
+ return getSkin(context, new SkinMetadata.Builder().id(TrinidadRenderingConstants.SIMPLE_DESKTOP_ID).build());
+ }
+
+ private final List<SkinProvider> _providers;
+
+ private static final String _SKIN_PROVIDER_CONTEXT =
+ "org.apache.myfaces.trinidadinternal.skin.provider.SkinProviderRegistry.Context";
+ private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SkinProviderRegistry.class);
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadBaseSkinProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadBaseSkinProvider.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadBaseSkinProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadBaseSkinProvider.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,199 @@
+/*
+ * 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.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+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 static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.CASABLANCA_DESKTOP_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.CASABLANCA_PDA_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.CASABLANCA_PORTLET_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.CASABLANCA_SKIN_FAMILY;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.CASABLANCA_STYLE_SHEET_NAME;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_DESKTOP_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_DESKTOP_STYLE_SHEET_NAME;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_PDA_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_PDA_STYLE_SHEET_NAME;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_PORTLET_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_PORTLET_STYLE_SHEET_NAME;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.MINIMAL_SKIN_FAMILY;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_DESKTOP_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_DESKTOP_LOCATION;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_PDA_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_PDA_LOCATION;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_PORTLET_ID;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_PORTLET_LOCATION;
+import static org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants.SIMPLE_SKIN_FAMILY;
+
+/**
+ * This SkinProvider creates the very base skins such as simple, minimal and casablanca
+ */
+public class TrinidadBaseSkinProvider extends BaseSkinProvider
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(FacesContext context)
+ {
+ return Collections.unmodifiableCollection(_METADATA);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Skin loadAvailableSkin(FacesContext context, SkinMetadata search)
+ {
+ // avoid round trips to SkinProviderRegistry for trinidad base skins
+ // any base skin used in this provider is also a static skin and can be loaded locally
+ // there fore load the base skins locally
+
+ Skin skin = getSkins().get(search);
+
+ if (skin != null)
+ {
+ return skin;
+ }
+
+ Skin loadedSkin = null;
+ Skin parentSkin = null;
+
+ if (search == _CASABLANCA_DESKTOP_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_DESKTOP_METADATA);
+ loadedSkin = new CasablancaDesktopSkin(parentSkin);
+ }
+ else if (search == _CASABLANCA_PDA_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_PDA_METADATA);
+ loadedSkin = new CasablancaPdaSkin(parentSkin);
+ }
+ else if (search == _CASABLANCA_PORTLET_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_PORTLET_METADATA);
+ loadedSkin = new CasablancaPortletSkin(parentSkin);
+ }
+ else if (search == _MINIMAL_DESKTOP_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_DESKTOP_METADATA);
+ loadedSkin = new MinimalDesktopSkinExtension(parentSkin);
+ }
+ else if (search == _MINIMAL_PDA_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_PDA_METADATA);
+ loadedSkin = new MinimalPdaSkinExtension(parentSkin);
+ }
+ else if (search == _MINIMAL_PORTLET_METADATA)
+ {
+ parentSkin = _loadBaseSkinAndRegisterIfRequired(context, _SIMPLE_PORTLET_METADATA);
+ loadedSkin = new MinimalPortletSkinExtension(parentSkin);
+ }
+ else if (search == _SIMPLE_DESKTOP_METADATA)
+ {
+ loadedSkin = new SimpleDesktopSkin();
+ }
+ else if (search == _SIMPLE_PDA_METADATA)
+ {
+ loadedSkin = new SimplePdaSkin();
+ }
+ else if (search == _SIMPLE_PORTLET_METADATA)
+ {
+ loadedSkin = new SimplePortletSkin();
+ }
+
+ return loadedSkin;
+ }
+
+ private Skin _loadBaseSkinAndRegisterIfRequired(FacesContext context, SkinMetadata metadata)
+ {
+ Skin skin = getSkins().get(metadata);
+
+ if (skin == null)
+ {
+ skin = loadAvailableSkin(context, metadata);
+ addSkin(metadata, skin);
+ }
+
+ return skin;
+ }
+
+
+ private final static Collection<SkinMetadata> _METADATA;
+ private final static SkinMetadata _SIMPLE_DESKTOP_METADATA;
+ private final static SkinMetadata _SIMPLE_PDA_METADATA;
+ private final static SkinMetadata _SIMPLE_PORTLET_METADATA;
+ private final static SkinMetadata _MINIMAL_DESKTOP_METADATA;
+ private final static SkinMetadata _MINIMAL_PORTLET_METADATA;
+ private final static SkinMetadata _MINIMAL_PDA_METADATA;
+ private final static SkinMetadata _CASABLANCA_DESKTOP_METADATA;
+ private final static SkinMetadata _CASABLANCA_PDA_METADATA;
+ private final static SkinMetadata _CASABLANCA_PORTLET_METADATA;
+
+ static {
+ _SIMPLE_DESKTOP_METADATA = new SkinMetadata.Builder().id(SIMPLE_DESKTOP_ID).family(SIMPLE_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.DESKTOP).styleSheetName(SIMPLE_DESKTOP_LOCATION).build();
+ _SIMPLE_PDA_METADATA = new SkinMetadata.Builder().id(SIMPLE_PDA_ID).family(SIMPLE_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PDA).styleSheetName(SIMPLE_PDA_LOCATION).build();
+ _SIMPLE_PORTLET_METADATA = new SkinMetadata.Builder().id(SIMPLE_PORTLET_ID).family(SIMPLE_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PORTLET).styleSheetName(SIMPLE_PORTLET_LOCATION).build();
+ _MINIMAL_DESKTOP_METADATA= new SkinMetadata.Builder().id(MINIMAL_DESKTOP_ID).family(MINIMAL_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.DESKTOP).baseSkinId(SIMPLE_DESKTOP_ID)
+ .styleSheetName(MINIMAL_DESKTOP_STYLE_SHEET_NAME).build();
+ _MINIMAL_PDA_METADATA = new SkinMetadata.Builder().id(MINIMAL_PDA_ID).family(MINIMAL_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PDA).baseSkinId(SIMPLE_PDA_ID)
+ .styleSheetName(MINIMAL_PDA_STYLE_SHEET_NAME).build();
+ _MINIMAL_PORTLET_METADATA = new SkinMetadata.Builder().id(MINIMAL_PORTLET_ID).family(MINIMAL_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PORTLET).baseSkinId(SIMPLE_PORTLET_ID)
+ .styleSheetName(MINIMAL_PORTLET_STYLE_SHEET_NAME).build();
+ _CASABLANCA_DESKTOP_METADATA = new SkinMetadata.Builder().id(CASABLANCA_DESKTOP_ID).family(CASABLANCA_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.DESKTOP).baseSkinId(SIMPLE_DESKTOP_ID)
+ .styleSheetName(CASABLANCA_STYLE_SHEET_NAME).build();
+ _CASABLANCA_PDA_METADATA = new SkinMetadata.Builder().id(CASABLANCA_PDA_ID).family(CASABLANCA_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PDA).baseSkinId(SIMPLE_PDA_ID)
+ .styleSheetName(CASABLANCA_STYLE_SHEET_NAME).build();
+ _CASABLANCA_PORTLET_METADATA = new SkinMetadata.Builder().id(CASABLANCA_PORTLET_ID).family(CASABLANCA_SKIN_FAMILY)
+ .renderKitId(SkinMetadata.RenderKitId.PORTLET).baseSkinId(SIMPLE_PORTLET_ID).build();
+
+ _METADATA = new ArrayList<SkinMetadata>(9);
+ _METADATA.add(_SIMPLE_DESKTOP_METADATA);
+ _METADATA.add(_SIMPLE_PDA_METADATA);
+ _METADATA.add(_SIMPLE_PORTLET_METADATA);
+ _METADATA.add(_MINIMAL_DESKTOP_METADATA);
+ _METADATA.add(_MINIMAL_PDA_METADATA);
+ _METADATA.add(_MINIMAL_PORTLET_METADATA);
+ _METADATA.add(_CASABLANCA_DESKTOP_METADATA);
+ _METADATA.add(_CASABLANCA_PDA_METADATA);
+ _METADATA.add(_CASABLANCA_PORTLET_METADATA);
+ }
+}
\ No newline at end of file
Added: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java?rev=1533115&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java (added)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/provider/TrinidadSkinProvider.java Thu Oct 17 15:25:57 2013
@@ -0,0 +1,223 @@
+/*
+ * 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.provider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+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.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinAddition;
+import org.apache.myfaces.trinidad.skin.SkinMetadata;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidad.skin.SkinVersion;
+import org.apache.myfaces.trinidadinternal.config.LazyValueExpression;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants;
+import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+import org.apache.myfaces.trinidadinternal.skin.parse.SkinsNode;
+
+/**
+ * This is the Trinidad's SkinProvider for loading skins from trinidad-skins.xml. This provider reads and caches
+ * trinidad-skins.xml from various sources like META-INF, WEB-INF and SkinResourceLoader API during its initialization.
+ * Subsequently the Skin objects are created lazily using the cached metadata, only when it is first requested for.
+ */
+public final class TrinidadSkinProvider extends BaseSkinProvider
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<SkinMetadata> getSkinMetadata(FacesContext context)
+ {
+ // already initialized to unmodifiableCollection
+ return _skinMetadata;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Skin loadAvailableSkin(FacesContext context, SkinMetadata skinMetadata)
+ {
+ SkinMetadata matchingNode = null;
+
+ for (SkinMetadata node : _skinMetadata)
+ {
+ if (skinMetadata.getId().equals(node.getId()))
+ {
+ matchingNode = node;
+ break;
+ }
+ }
+
+ if (matchingNode == null)
+ {
+ // This cannot happen because base class checks for availability before it calls for the skin to be loaded
+ if (_LOG.isSevere())
+ _LOG.severe("SP_LOADING_UNKNOWN_SKIN", new Object[] {skinMetadata.getId()});
+
+ throw new NullPointerException(_LOG.getMessage("SP_LOADING_UNKNOWN_SKIN", new Object[] {skinMetadata.getId()}));
+ }
+
+ String id = matchingNode.getId();
+ String family = matchingNode.getFamily();
+ String renderKitId = matchingNode.getRenderKitId();
+ Skin baseSkin = null;
+ String baseSkinId = matchingNode.getBaseSkinId();
+ SkinProvider provider = SkinUtils.getSkinProvider(context);
+
+ if (provider != null && baseSkinId != null)
+ baseSkin = provider.getSkin(context, new SkinMetadata.Builder().id(baseSkinId).build());
+
+ // if there is no base skin then use the default base skin for the renderKit
+ if (baseSkin == null)
+ baseSkin = _getDefaultBaseSkin(provider, renderKitId);
+
+ if (id == null)
+ throw new NullPointerException(_LOG.getMessage("NULL_SKIN_ID"));
+
+ if (family == null)
+ throw new NullPointerException("Null family");
+
+ if (_LOG.isFine())
+ _LOG.fine("Creating skin extension for : " + skinMetadata);
+
+ // features object itself cannot be null
+ Skin loadedSkin = new SkinExtension(baseSkin, matchingNode);
+
+ if (_skinAdditionNodes != null)
+ for (SkinAddition addition : _skinAdditionNodes)
+ {
+ String additionSkinId = addition.getSkinId();
+
+ if (id.equals(additionSkinId))
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Adding skin addition : " + addition);
+
+ loadedSkin.addSkinAddition(addition);
+ }
+
+ if (baseSkinId.equals(additionSkinId)
+ && !_hasSkinAddition(baseSkin.getSkinAdditions(), addition))
+ {
+ if (_LOG.isFine())
+ _LOG.fine("Adding parent skin addition : " + addition);
+
+ baseSkin.addSkinAddition(addition);
+ }
+ }
+
+ return loadedSkin;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void initialize(FacesContext context)
+ {
+ if (context == null || context.getExternalContext() == null)
+ {
+ return;
+ }
+
+ if (_skinMetadata == null)
+ {
+ if (_LOG.isFine())
+ _LOG.fine("init provider.");
+
+ // only now do initialization
+ ExternalContext extCtxt = context.getExternalContext();
+ List<SkinsNode> skinsNodes = SkinUtils.buildSkinsNodes(extCtxt);
+ List<SkinMetadata> skinNodes = new ArrayList<SkinMetadata>();
+ List<SkinAddition> skinAdditionNodes = new ArrayList<SkinAddition>();
+
+ for (SkinsNode node : skinsNodes)
+ {
+ if (node != null)
+ {
+ skinNodes.addAll(node.getSkinNodes());
+ skinAdditionNodes.addAll(node.getSkinAdditionNodes());
+ }
+ }
+
+ if (skinNodes.isEmpty())
+ _skinMetadata = Collections.emptyList();
+ else
+ _skinMetadata = Collections.unmodifiableList(skinNodes);
+
+ if (skinAdditionNodes.isEmpty())
+ _skinAdditionNodes = Collections.emptyList();
+ else
+ _skinAdditionNodes = Collections.unmodifiableList(skinAdditionNodes);
+
+ if (_LOG.isFine())
+ {
+ _LOG.fine("trindiad-skins loaded: " + _skinMetadata.size());
+ _LOG.fine("trindiad-skins additions loaded: " + _skinAdditionNodes.size());
+ }
+ }
+ }
+
+ private boolean _hasSkinAddition(List<SkinAddition> additions, SkinAddition search)
+ {
+ if (search == null)
+ return false;
+
+ // here we check only stylesheet name as an addition with a stylesheet name needs to added only once
+ for (SkinAddition addn : additions)
+ if (addn != null && search.getStyleSheetName().equals(addn.getStyleSheetName()))
+ return true;
+
+ return false;
+ }
+
+ private static Skin _getDefaultBaseSkin(SkinProvider provider, String renderKitId)
+ {
+ String baseSkinId;
+
+ if (TrinidadRenderingConstants.APACHE_TRINIDAD_PDA.equals(renderKitId))
+ baseSkinId = TrinidadRenderingConstants.SIMPLE_PDA_ID;
+ else if (TrinidadRenderingConstants.APACHE_TRINIDAD_PORTLET.equals(renderKitId))
+ baseSkinId = TrinidadRenderingConstants.SIMPLE_PORTLET_ID;
+ else
+ baseSkinId = TrinidadRenderingConstants.SIMPLE_DESKTOP_ID;
+
+ Skin baseSkin = provider.getSkin(null, new SkinMetadata.Builder().id(baseSkinId).build());
+
+ // this will never be null because we are asking for the default simple skin
+ assert (baseSkin != null);
+ return baseSkin;
+ }
+
+ private List<SkinMetadata> _skinMetadata;
+ private List<SkinAddition> _skinAdditionNodes;
+
+ private final static TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TrinidadSkinProvider.class);
+}
\ No newline at end of file
Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts Thu Oct 17 15:25:57 2013
@@ -247,8 +247,8 @@
<!-- RENDERER_NOT_FOUND -->
<resource key="RENDERER_NOT_FOUND">Renderer ''{0}'' not found for component family ''{1}''</resource>
-<!-- NO_SKIN_FACTORY -->
-<resource key="NO_SKIN_FACTORY">There is no SkinFactory</resource>
+<!-- NO_SKIN_PROVIDER -->
+<resource key="NO_SKIN_PROVIDER">There is no SkinProvider</resource>
<!-- STYLESHEETDOCUMENT_ID_NOT_MATCH_LOCAL_SKIN -->
<resource key="STYLESHEETDOCUMENT_ID_NOT_MATCH_LOCAL_SKIN">
@@ -262,8 +262,8 @@ The skin {0} specified on the requestMap
<!-- REQUESTMAP_SKIN_NOT_USED_BECAUSE_NOT_EXIST -->
<resource key="REQUESTMAP_SKIN_NOT_USED_BECAUSE_NOT_EXIST">The skin {0} specified on the requestMap will not be used because it does not exist.</resource>
-<!-- CANNOT_GET_SKIN_FROM_SKINFACTORY -->
-<resource key="CANNOT_GET_SKIN_FROM_SKINFACTORY">Could not get skin {0} from the SkinFactory</resource>
+<!-- CANNOT_GET_SKIN_FROM_SKINPROVIDER -->
+<resource key="CANNOT_GET_SKIN_FROM_SKINPROVIDER">Could not get skin {0} from the SkinProvider</resource>
<!-- SKIN_CIRCULAR_INCLUDE_ERROR -->
<resource key="SKIN_CIRCULAR_INCLUDE_ERROR">Circular dependency detected in skin reference icon {0}</resource>
@@ -468,7 +468,22 @@ The skin {0} specified on the requestMap
<resource key="ERR_PARSING_SKIN_SELECTOR">Error reading from the skin css file. There is an extra comma in selector: {0}</resource>
<!-- CANNOT_ADD_SKIN -->
-<resource key="CANNOT_ADD_SKIN">Can't add Skin with null skinId or null skin</resource>
+<resource key="CANNOT_ADD_SKIN">Can't add Skin with null skin metadata or null skin</resource>
+
+<!-- NULL_FC_SKIN_METADATA -->
+<resource key="NULL_FC_SKIN_METADATA">Cannot create skin extension with null context or null skin metadata.</resource>
+
+<!-- NULL_FC_SKIN_BASE_SKIN_METADATA -->
+<resource key="NULL_FC_SKIN_BASE_SKIN_METADATA">Cannot create skin extension with null context or null skin metadata or null base skin metadata.</resource>
+
+<!-- NULL_SKIN_METADATA_TO_CREATE_SKIN -->
+<resource key="NULL_BASE_SKIN_ID">Make sure that base skin id is mentioned in the skin metadata. Base skin is mandatory for creating a skin extension.</resource>
+
+ <!-- INVALID_BASE_SKIN_ID -->
+<resource key="INVALID_BASE_SKIN_ID">Skin id in base skin metadata does not match with the base skin id in skin metadata.</resource>
+
+<!-- INVALID_BASE_SKIN -->
+<resource key="INVALID_BASE_SKIN">Base skin provided cannot be obtained using SkinProvider. Make sure that the base skin information provided is valid and supported by at least one SkinProvider.</resource>
<!-- DUPLICATE_ADD_SKIN_TO_SKIN_FACTORY -->
<resource key="DUPLICATE_ADD_SKIN_TO_SKIN_FACTORY">The previously added {0} skin has been added again. If you cached this skin in your application, you might get inconsistent results. Check for duplicate trinidad-skins.xml files on the classpath.</resource>
@@ -1209,4 +1224,14 @@ The skin {0} specified on the requestMap
<resource key="INVALID_SURROGATE_CHAR">During encoding, a high surrogate character was found, but the codePoint was invalid. ch is {0}, codePoint is {1} and index is {2}.</resource>
+<resource key="SP_CANNOT_FIND_SKIN_WITHOUT_FAMILY_OR_ID">Cannot search for skin without skinId or skin family.</resource>
+
+<resource key="SP_FINDING_SKIN_FOR">Searching for skin {0}.</resource>
+
+<resource key="SP_CANNOT_FIND_MATCHING_SKIN_ID">Can''t find a skin that matches skinId {0}.</resource>
+
+<resource key="SP_CANNOT_FIND_MATCHING_SKIN">Can''t find a skin that matches family {0} and renderkit {1}.</resource>
+
+<resource key="SP_LOADING_UNKNOWN_SKIN">Cannot load skin with id {0}. This skin is unknown to the current TrinidadSkinProvider.</resource>
+
</resources>
Modified: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitBootstrap.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitBootstrap.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitBootstrap.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitBootstrap.java Thu Oct 17 15:25:57 2013
@@ -38,7 +38,6 @@ import org.apache.myfaces.trinidadintern
import org.apache.myfaces.trinidadinternal.agent.AgentImpl;
import org.apache.myfaces.trinidadinternal.skin.SkinFactoryImpl;
-import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
public class RenderKitBootstrap
{
@@ -151,11 +150,6 @@ public class RenderKitBootstrap
if (SkinFactory.getFactory() == null)
{
SkinFactory.setFactory(new SkinFactoryImpl());
-
- // register the base skins
- // =-=AEW Because we don't have a "ServletContext", we can't
- // find any custom skins
- SkinUtils.registerBaseSkins();
}
}
Modified: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitTestCase.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitTestCase.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/RenderKitTestCase.java Thu Oct 17 15:25:57 2013
@@ -48,14 +48,16 @@ import org.apache.commons.lang.StringUti
import org.apache.myfaces.trinidad.context.Agent;
import org.apache.myfaces.trinidad.context.RequestContext;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
import org.apache.myfaces.trinidad.util.Service;
import org.apache.myfaces.trinidadbuild.test.FacesTestCase;
import org.apache.myfaces.trinidadinternal.io.XhtmlResponseWriter;
+import org.apache.myfaces.trinidadinternal.skin.provider.ExternalSkinProvider;
+import org.apache.myfaces.trinidadinternal.skin.provider.SkinProviderRegistry;
import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
@@ -185,7 +187,10 @@ abstract public class RenderKitTestCase
Application mockApplication,
boolean testMode)
{
- return new MFacesContext(mockApplication, testMode);
+ MFacesContext ctx = new MFacesContext(mockApplication, testMode);
+ ctx.getExternalContext().getApplicationMap().put(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY, new ExternalSkinProvider());
+ ctx.getExternalContext().getApplicationMap().put(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY, new SkinProviderRegistry());
+ return ctx;
}
protected MRequestContext createRequestContext()
Modified: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/ui/laf/base/xhtml/XhtmlLafUtilsTest.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/ui/laf/base/xhtml/XhtmlLafUtilsTest.java?rev=1533115&r1=1533114&r2=1533115&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/ui/laf/base/xhtml/XhtmlLafUtilsTest.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/ui/laf/base/xhtml/XhtmlLafUtilsTest.java Thu Oct 17 15:25:57 2013
@@ -21,18 +21,16 @@ package org.apache.myfaces.trinidadinter
import java.util.Locale;
import javax.faces.component.UIViewRoot;
-import javax.faces.context.ResponseWriter;
import junit.framework.TestCase;
-import org.apache.myfaces.trinidad.context.RenderingContext;
import org.apache.myfaces.trinidad.context.RequestContext;
-import org.apache.myfaces.trinidadinternal.io.XhtmlResponseWriter;
-import org.apache.myfaces.trinidadinternal.renderkit.FacesConfigInfo;
+import org.apache.myfaces.trinidad.skin.SkinProvider;
+import org.apache.myfaces.trinidadinternal.skin.provider.ExternalSkinProvider;
+import org.apache.myfaces.trinidadinternal.skin.provider.SkinProviderRegistry;
import org.apache.myfaces.trinidadinternal.renderkit.MApplication;
import org.apache.myfaces.trinidadinternal.renderkit.MFacesContext;
import org.apache.myfaces.trinidadinternal.renderkit.MRequestContext;
-import org.apache.myfaces.trinidadinternal.renderkit.NullWriter;
import org.apache.myfaces.trinidadinternal.renderkit.RenderKitBootstrap;
import org.apache.myfaces.trinidadinternal.renderkit.core.CoreRenderingContext;
@@ -69,6 +67,8 @@ public class XhtmlLafUtilsTest extends T
_requestContext.setAgent(RenderKitBootstrap.getGeckoAgent());
_requestContext.setRightToLeft(false);
_requestContext.setAccessibilityMode(null);
+ _facesContext.getExternalContext().getApplicationMap().put(ExternalSkinProvider.EXTERNAL_SKIN_PROVIDER_KEY, new ExternalSkinProvider());
+ _facesContext.getExternalContext().getApplicationMap().put(SkinProvider.SKIN_PROVIDER_INSTANCE_KEY, new SkinProviderRegistry());
UIViewRoot root = RenderKitBootstrap.createUIViewRoot(_facesContext);
root.setRenderKitId("org.apache.myfaces.trinidad.core");