View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.facelets.extension;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.util.ComponentUtils;
24  
25  import javax.el.ELException;
26  import javax.faces.FacesException;
27  import javax.faces.application.Application;
28  import javax.faces.component.UIComponent;
29  import javax.faces.component.UIViewRoot;
30  import javax.faces.view.facelets.ComponentConfig;
31  import javax.faces.view.facelets.ComponentHandler;
32  import javax.faces.view.facelets.FaceletContext;
33  import javax.faces.view.facelets.MetaRuleset;
34  import javax.faces.view.facelets.Metadata;
35  import javax.faces.view.facelets.TagAttribute;
36  import java.io.IOException;
37  
38  
39  /**
40   * Base class of the Facelets handlers for the <tx:menuXXX /> extension tags.
41   */
42  public abstract class TobagoMenuExtensionHandler extends ComponentHandler {
43  
44    private Class subComponentLastType = Object.class;
45    private Metadata subComponentMapper;
46    private TagAttribute fieldIdAttribute;
47  
48    public TobagoMenuExtensionHandler(ComponentConfig config) {
49      super(config);
50      fieldIdAttribute = getAttribute("fieldId");
51    }
52  
53    protected abstract String getSubComponentType();
54  
55    protected abstract String getSubRendererType();
56  
57    protected abstract String getFacetName();
58  
59    public void applyNextHandler(FaceletContext faceletContext, UIComponent menuCommand)
60        throws IOException, FacesException, ELException {
61      if (ComponentHandler.isNew(menuCommand)) {
62        UIComponent component = (UIComponent) menuCommand.getFacets().remove(getFacetName());
63        nextHandler.apply(faceletContext, component);
64        menuCommand.getFacets().put(getFacetName(), component);
65      } else {
66        nextHandler.apply(faceletContext, menuCommand.getFacet(getFacetName()));
67      }
68    }
69  
70    public void onComponentCreated(FaceletContext faceletContext, UIComponent menuCommand, UIComponent parent) {
71  
72      Application application = faceletContext.getFacesContext().getApplication();
73      UIViewRoot root = ComponentUtils.findViewRoot(faceletContext, parent);
74      UIComponent component = application.createComponent(getSubComponentType());
75      final String uid;
76      if (fieldIdAttribute !=  null) {
77        uid = fieldIdAttribute.getValue(faceletContext);
78      } else {
79        uid = root.createUniqueId();
80      }
81      component.setId(uid);
82      component.setRendererType(getSubRendererType());
83      setSubComponentAttributes(faceletContext, component);
84      menuCommand.getFacets().put(getFacetName(), component);
85    }
86  
87    private void setSubComponentAttributes(FaceletContext ctx, Object instance) {
88      if (instance != null) {
89        Class type = instance.getClass();
90        if (subComponentMapper == null || !subComponentLastType.equals(type)) {
91          subComponentLastType = type;
92          subComponentMapper = createSubComponentMetaRuleset(type).finish();
93        }
94        subComponentMapper.applyMetadata(ctx, instance);
95      }
96    }
97  
98    protected MetaRuleset createSubComponentMetaRuleset(Class aClass) {
99      MetaRuleset metaRuleset = super.createMetaRuleset(aClass);
100     TagAttribute [] attrs = tag.getAttributes().getAll();
101     for (int i = 0; i < attrs.length; i++) {
102       TagAttribute attr = attrs[i];
103       if (!(attr.getLocalName().equals(Attributes.CONVERTER)
104           || attr.getLocalName().equals(Attributes.VALUE))) {
105         metaRuleset.ignore(attr.getLocalName());
106       }
107     }
108     return metaRuleset;
109   }
110 
111   protected MetaRuleset createMetaRuleset(Class aClass) {
112     MetaRuleset metaRuleset = super.createMetaRuleset(aClass);
113     metaRuleset.ignore(Attributes.CONVERTER);
114     metaRuleset.ignore(Attributes.VALUE);
115     return metaRuleset;
116   }
117 }