1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21 
22 package org.apache.openoffice.ooxml.parser.action;
23 
24 import java.util.HashMap;
25 import java.util.Map;
26 
27 import org.apache.openoffice.ooxml.parser.NameMap;
28 
29 /** Manage actions that are bound to states and XML events.
30  */
31 public class ActionManager
32 {
ActionManager( final NameMap aStateNameToIdMap)33     public ActionManager (
34         final NameMap aStateNameToIdMap)
35     {
36         maStateNameToIdMap = aStateNameToIdMap;
37         maAllStatesActions = new ActionDescriptor(0,"*");
38         maStateToActionsMap = new HashMap<>();
39     }
40 
41 
42 
43 
44     /** Add an action for an element start.
45      *  @param sStateSelector
46      *      The element is specified via a state name.  This allows one element
47      *      that leads to different complex types to have different actions,
48      *      depending on the complex type.
49      *      The selector value can be a full state name (including the namespace
50      *      prefix and CT prefix, e.g. w06_CT_Table) or a regular expression
51      *      (e.g. .*_CT_Table to match w06_CT_Table and w12_CT_Table).
52      *      The action is bound to all matching states.
53      *  @param aAction
54      *      The action to call on entering any of the states that match the
55      *      selector.
56      */
AddElementStartAction( final String sStateSelector, final IAction aAction)57     public void AddElementStartAction (
58         final String sStateSelector,
59         final IAction aAction)
60     {
61         AddAction(sStateSelector, aAction, ActionTrigger.ElementStart);
62     }
63 
64 
65 
66 
67     /** Add an action for an element end.
68      *  @see AddElementStartAction.
69      */
AddElementEndAction( final String sStateSelector, final IAction aAction)70     public void AddElementEndAction (
71         final String sStateSelector,
72         final IAction aAction)
73     {
74         AddAction(sStateSelector, aAction, ActionTrigger.ElementEnd);
75     }
76 
77 
78 
79 
80     /** Add an action for XML text events.
81      *  @see AddElementStartAction.
82      */
AddTextAction( final String sStateSelector, final IAction aAction)83     public void AddTextAction (
84         final String sStateSelector,
85         final IAction aAction)
86     {
87         AddAction(sStateSelector, aAction, ActionTrigger.Text);
88     }
89 
90 
91 
92 
93     /** Return an iterable object that gives access to all actions
94      *  bound to the given state and trigger.
95      *  Return value can be null when there are no actions bound to the state
96      *  and trigger.
97      */
GetActions( final int nStateId, final ActionTrigger eTrigger)98     public Iterable<IAction> GetActions (
99         final int nStateId,
100         final ActionTrigger eTrigger)
101     {
102         final ActionDescriptor aOneStateActionsDescriptor = maStateToActionsMap.get(nStateId);
103         final Iterable<IAction> aOneStateActions = aOneStateActionsDescriptor!=null
104             ? aOneStateActionsDescriptor.GetActions(eTrigger)
105             : null;
106         final Iterable<IAction> aAllStateActions = maAllStatesActions.GetActions(eTrigger);
107 
108         if (aOneStateActions == null)
109             return aAllStateActions;
110         else if (aAllStateActions == null)
111             return aOneStateActions;
112         else
113             return new ActionIterator(aOneStateActions, aAllStateActions);
114     }
115 
116 
117 
118 
AddAction( final String sStateSelector, final IAction aAction, final ActionTrigger eTrigger)119     private void AddAction (
120         final String sStateSelector,
121         final IAction aAction,
122         final ActionTrigger eTrigger)
123     {
124         if (sStateSelector.equals("*"))
125         {
126             // Simple optimization when an action is defined for all states.
127             maAllStatesActions.AddAction(aAction, eTrigger);
128         }
129         else if (sStateSelector.contains("*") || sStateSelector.contains("?"))
130         {
131             // The state selector contains wildcards.  We have to iterate over
132             // all state names to find the matching ones.
133             for (final int nStateId : maStateNameToIdMap.GetMatchingStateIds(sStateSelector))
134             {
135                 GetActionDescriptor(nStateId).AddAction(aAction, eTrigger);
136             }
137         }
138         else
139         {
140             final int nStateId = maStateNameToIdMap.GetIdForName(sStateSelector);
141             GetActionDescriptor(nStateId).AddAction(aAction, eTrigger);
142         }
143     }
144 
145 
146 
147 
GetActionDescriptor(final int nStateId)148     private ActionDescriptor GetActionDescriptor (final int nStateId)
149     {
150         ActionDescriptor aDescriptor = maStateToActionsMap.get(nStateId);
151         if (aDescriptor == null)
152         {
153             aDescriptor = new ActionDescriptor(nStateId, maStateNameToIdMap.GetNameForId(nStateId));
154             maStateToActionsMap.put(nStateId, aDescriptor);
155         }
156         return aDescriptor;
157     }
158 
159 
160 
161 
162     private final NameMap maStateNameToIdMap;
163     private final ActionDescriptor maAllStatesActions;
164     private final Map<Integer,ActionDescriptor> maStateToActionsMap;
165 }
166