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.event;
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import javax.el.ValueExpression;
26  import javax.faces.component.StateHolder;
27  import javax.faces.component.UIComponentBase;
28  import javax.faces.context.FacesContext;
29  import java.lang.invoke.MethodHandles;
30  
31  public class ValueExpressionSheetStateChangeListener implements SheetStateChangeListener, StateHolder {
32  
33    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
34  
35    private String type;
36    private ValueExpression valueExpression;
37  
38    public ValueExpressionSheetStateChangeListener() {
39    }
40  
41    public ValueExpressionSheetStateChangeListener(final String type, final ValueExpression valueExpression) {
42      this.type = type;
43      this.valueExpression = valueExpression;
44    }
45  
46    @Override
47    public void processSheetStateChange(final SheetStateChangeEvent sheetStateChangeEvent) {
48      final SheetStateChangeListener handler = getSheetStateChangeListener();
49      if (handler != null) {
50        handler.processSheetStateChange(sheetStateChangeEvent);
51      } else {
52        LOG.error("Ignoring SheetStateChangeEvent. No SheetStateChangeListener found.");
53      }
54    }
55  
56    @Override
57    public Object saveState(final FacesContext context) {
58      final Object[] state = new Object[2];
59      state[0] = UIComponentBase.saveAttachedState(context, valueExpression);
60      state[1] = type;
61      return state;
62    }
63  
64    @Override
65    public void restoreState(final FacesContext context, final Object state) {
66      final Object[] values = (Object[]) state;
67      valueExpression = (ValueExpression) UIComponentBase.restoreAttachedState(context, values[0]);
68      type = (String) values[1];
69  
70    }
71  
72    @Override
73    public boolean isTransient() {
74      return false;
75    }
76  
77    @Override
78    public void setTransient(final boolean newTransientValue) {
79      // ignore
80    }
81  
82    private SheetStateChangeListener getSheetStateChangeListener() {
83      SheetStateChangeListener handler = null;
84      if (valueExpression != null) {
85        final Object obj = valueExpression.getValue(FacesContext.getCurrentInstance().getELContext());
86        if (obj != null && obj instanceof SheetStateChangeListener) {
87          handler = (SheetStateChangeListener) obj;
88        }
89      }
90      if (handler == null && type != null) {
91        handler = createSheetStateChangeListener(type);
92        if (handler != null && valueExpression != null) {
93          valueExpression.setValue(FacesContext.getCurrentInstance().getELContext(), handler);
94        }
95      }
96      return handler;
97    }
98  
99    private SheetStateChangeListener createSheetStateChangeListener(final String className) {
100     try {
101       final Class clazz = getClass().getClassLoader().loadClass(className);
102       return (SheetStateChangeListener) clazz.newInstance();
103     } catch (final Exception e) {
104       LOG.error("", e);
105     }
106     return null;
107   }
108 }