/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2005-2007 The Apache Software Foundation
*
* Licensed 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 com.sun.faces.facelets.tag.composite;
import com.sun.faces.facelets.el.TagValueExpression;
import com.sun.faces.util.Util;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.component.UIComponent;
import javax.faces.application.ProjectStage;
import javax.el.ValueExpression;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.beans.FeatureDescriptor;
class PropertyHandlerManager {
private static final Map<String,PropertyHandler> ALL_HANDLERS =
new HashMap<>(12, 1.0f);
static {
ALL_HANDLERS.put("targets", new StringValueExpressionPropertyHandler());
ALL_HANDLERS.put("targetAttributeName", new StringValueExpressionPropertyHandler());
ALL_HANDLERS.put("method-signature", new StringValueExpressionPropertyHandler());
ALL_HANDLERS.put("type", new StringValueExpressionPropertyHandler());
ALL_HANDLERS.put("default", new DefaultPropertyHandler());
ALL_HANDLERS.put("displayName", new DisplayNamePropertyHandler());
ALL_HANDLERS.put("shortDescription", new ShortDescriptionPropertyHandler());
ALL_HANDLERS.put("expert", new ExpertPropertyHandler());
ALL_HANDLERS.put("hidden", new HiddenPropertyHandler());
ALL_HANDLERS.put("preferred", new PreferredPropertyHandler());
ALL_HANDLERS.put("required", new BooleanValueExpressionPropertyHandler());
ALL_HANDLERS.put("name", new NamePropertyHandler());
ALL_HANDLERS.put("componentType", new ComponentTypePropertyHandler());
}
private static final String[] DEV_ONLY_ATTRIBUTES = {
"displayName",
"shortDescription",
"export",
"hidden",
"preferred"
};
static {
Arrays.sort(DEV_ONLY_ATTRIBUTES);
}
private Map<String,PropertyHandler> managedHandlers;
private PropertyHandler genericHandler =
new ObjectValueExpressionPropertyHandler();
// -------------------------------------------------------- Constructors
private PropertyHandlerManager(Map<String,PropertyHandler> managedHandlers) {
this.managedHandlers = managedHandlers;
}
// ------------------------------------------------- Package Private Methods
static PropertyHandlerManager getInstance(String[] attributes) {
Map<String,PropertyHandler> handlers =
new HashMap<>(attributes.length, 1.0f);
for (String attribute : attributes) {
handlers.put(attribute, ALL_HANDLERS.get(attribute));
}
return new PropertyHandlerManager(handlers);
}
PropertyHandler getHandler(FaceletContext ctx, String name) {
if (!ctx.getFacesContext().isProjectStage(ProjectStage.Development)) {
if (Arrays.binarySearch(DEV_ONLY_ATTRIBUTES, name) >= 0) {
return null;
}
}
PropertyHandler h = managedHandlers.get(name);
return ((h != null) ? h : genericHandler);
}
// ---------------------------------------------------------- Nested Classes
private abstract static class BooleanFeatureDescriptorPropertyHandler
implements TypedPropertyHandler {
@Override
public Class<?> getEvalType() {
return Boolean.class;
}
} // END BooleanFeatureDescriptorPropertyHandler
private abstract static class StringFeatureDescriptorPropertyHandler
implements TypedPropertyHandler {
@Override
public Class<?> getEvalType() {
return String.class;
}
} // END StringPropertyDescriptionPropertyHandler
private abstract static class TypedValueExpressionPropertyHandler
implements TypedPropertyHandler {
@Override
public void apply(FaceletContext ctx,
String propName,
FeatureDescriptor target,
TagAttribute attribute) {
target.setValue(propName,
attribute.getValueExpression(ctx, getEvalType()));
}
@Override
public abstract Class<?> getEvalType();
} // END TypeValueExpressionPropertyHandler
private static final class NamePropertyHandler
extends StringFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx,
String propName,
FeatureDescriptor target,
TagAttribute attribute) {
ValueExpression ve = attribute.getValueExpression(ctx, getEvalType());
String v = (String) ve.getValue(ctx);
if (v != null) {
target.setShortDescription((String) ve.getValue(ctx));
}
}
}
private static final class ShortDescriptionPropertyHandler
extends StringFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx,
String propName,
FeatureDescriptor target,
TagAttribute attribute) {
ValueExpression ve = attribute.getValueExpression(ctx, getEvalType());
String v = (String) ve.getValue(ctx);
if (v != null) {
target.setShortDescription((String) ve.getValue(ctx));
}
}
} // END ShortDescriptionPropertyHandler
private static class StringValueExpressionPropertyHandler
extends TypedValueExpressionPropertyHandler {
@Override
public Class<?> getEvalType() {
return String.class;
}
} // END StringValueExpressionPropertyHandler
private static class ObjectValueExpressionPropertyHandler
extends TypedValueExpressionPropertyHandler {
@Override
public Class<?> getEvalType() {
return Object.class;
}
} // END ObjectValueExpressionPropertyHandler
/**
* This PropertyHandler will apply the default-value of a cc:attribute
* tag, taking an eventually provided type into account.
*/
private static class DefaultPropertyHandler
implements PropertyHandler {
@Override
public void apply(FaceletContext ctx,
String propName,
FeatureDescriptor target,
TagAttribute attribute) {
// try to get the type from the 'type'-attribute and default to
// Object.class, if no type-attribute was set.
Class<?> type = Object.class;
Object obj = target.getValue("type");
if ((null != obj) && !(obj instanceof Class)) {
TagValueExpression typeVE = (TagValueExpression) obj;
Object value = typeVE.getValue(ctx);
if (value instanceof Class<?>) {
type = (Class<?>) value;
} else if (value != null) {
try {
type = Util.loadClass(String.valueOf(value), this);
} catch (ClassNotFoundException ex) {
// Wrap the ClassNotFoundException into a
// RuntimeException, so that it can be unwrapped in the
// caller
throw new IllegalArgumentException(ex);
}
}
} else {
type = null != obj ? (Class) obj : Object.class;
}
target.setValue(propName, attribute.getValueExpression(ctx, type));
}
}
private static class ComponentTypePropertyHandler
extends StringValueExpressionPropertyHandler {
@Override
public void apply(FaceletContext ctx,
String propName,
FeatureDescriptor target,
TagAttribute attribute) {
super.apply(ctx,
UIComponent.COMPOSITE_COMPONENT_TYPE_KEY,
target,
attribute);
}
} // END ComponentTypePropertyHandler
private static final class PreferredPropertyHandler
extends BooleanFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx, String propName, FeatureDescriptor target, TagAttribute attribute) {
ValueExpression ve = attribute
.getValueExpression(ctx, getEvalType());
target.setPreferred((Boolean) ve.getValue(ctx));
}
} // END PreferredPropertyHandler
private static final class HiddenPropertyHandler
extends BooleanFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx, String propName, FeatureDescriptor target, TagAttribute attribute) {
ValueExpression ve = attribute
.getValueExpression(ctx, getEvalType());
target.setHidden((Boolean) ve.getValue(ctx));
}
} // END HiddenPropertyHandler
private static final class ExpertPropertyHandler
extends BooleanFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx, String propName, FeatureDescriptor target, TagAttribute attribute) {
ValueExpression ve = attribute
.getValueExpression(ctx, getEvalType());
target.setExpert((Boolean) ve.getValue(ctx));
}
} // END ExpertPropertyHandler
private static final class DisplayNamePropertyHandler
extends StringFeatureDescriptorPropertyHandler {
@Override
public void apply(FaceletContext ctx, String propName, FeatureDescriptor target, TagAttribute attribute) {
ValueExpression ve = attribute
.getValueExpression(ctx, getEvalType());
target.setDisplayName((String) ve.getValue(ctx));
}
} // END DisplayNamePropertyHandler
private static class BooleanValueExpressionPropertyHandler
extends TypedValueExpressionPropertyHandler {
@Override
public Class<?> getEvalType() {
return Boolean.class;
}
} // END BooleanValueExpressionPropertyHandler
}