PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/myfaces_core-2.1.10/src/myfaces-core-module-2.1.10/api/src/main/java/javax/faces/component/behavior/_AjaxBehaviorDeltaStateHelper.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 713 lines | 495 code | 65 blank | 153 comment | 67 complexity | 4f2be47247c9381428fbea6098812d82 MD5 | raw file
  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. package javax.faces.component.behavior;
  20. import javax.el.ValueExpression;
  21. import javax.faces.component.StateHelper;
  22. import javax.faces.component.StateHolder;
  23. import javax.faces.component.UIComponentBase;
  24. import javax.faces.context.FacesContext;
  25. import java.io.Serializable;
  26. import java.util.ArrayList;
  27. import java.util.Collection;
  28. import java.util.HashMap;
  29. import java.util.Iterator;
  30. import java.util.List;
  31. import java.util.Map;
  32. /**
  33. * @author Werner Punz (latest modification by $Author: struberg $)
  34. * @version $Revision: 1188267 $ $Date: 2011-10-24 13:09:08 -0500 (Mon, 24 Oct 2011) $
  35. *
  36. * Delta state helper to deal with the ajax
  37. * behavior delta states, cross ported
  38. * from our generic delta state, due to limitations
  39. * in the spec (sorry for the somewhat dirty code here maybe
  40. * we can unify both implementations by isolating a common protected interface)
  41. *
  42. * @since 2.0
  43. */
  44. class _AjaxBehaviorDeltaStateHelper<A extends AjaxBehavior> implements StateHelper
  45. {
  46. /**
  47. * We need to hold a component instance because:
  48. * <p/>
  49. * - The component is the one who knows if we are on initial or delta mode
  50. * - eval assume calls to component.ValueExpression
  51. */
  52. private A _target;
  53. /**
  54. * This map holds the full current state
  55. */
  56. private Map<Serializable, Object> _fullState;
  57. /**
  58. * This map only keep track of delta changes to be saved
  59. */
  60. private Map<Serializable, Object> _deltas;
  61. /**
  62. * This map keep track of StateHolder keys, to be saved when
  63. * saveState is called.
  64. */
  65. //private Set<Serializable> _stateHolderKeys;
  66. private boolean _transient = false;
  67. public _AjaxBehaviorDeltaStateHelper(A component)
  68. {
  69. super();
  70. this._target = component;
  71. _fullState = new HashMap<Serializable, Object>();
  72. _deltas = null;
  73. //_stateHolderKeys = new HashSet<Serializable>();
  74. }
  75. /**
  76. * Used to create delta map on demand
  77. *
  78. * @return
  79. */
  80. private boolean _createDeltas()
  81. {
  82. if (isInitialStateMarked())
  83. {
  84. if (_deltas == null)
  85. {
  86. _deltas = new HashMap<Serializable, Object>(2);
  87. }
  88. return true;
  89. }
  90. return false;
  91. }
  92. protected boolean isInitialStateMarked()
  93. {
  94. return _target.initialStateMarked();
  95. }
  96. public void add(Serializable key, Object value)
  97. {
  98. if (_createDeltas())
  99. {
  100. //Track delta case
  101. Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
  102. .get(key);
  103. if (deltaListMapValues == null)
  104. {
  105. deltaListMapValues = new InternalDeltaListMap<Object, Boolean>(
  106. 3);
  107. _deltas.put(key, deltaListMapValues);
  108. }
  109. deltaListMapValues.put(value, Boolean.TRUE);
  110. }
  111. //Handle change on full map
  112. List<Object> fullListValues = (List<Object>) _fullState.get(key);
  113. if (fullListValues == null)
  114. {
  115. fullListValues = new InternalList<Object>(3);
  116. _fullState.put(key, fullListValues);
  117. }
  118. fullListValues.add(value);
  119. }
  120. public Object eval(Serializable key)
  121. {
  122. Object returnValue = _fullState.get(key);
  123. if (returnValue != null)
  124. {
  125. return returnValue;
  126. }
  127. ValueExpression expression = _target.getValueExpression(key
  128. .toString());
  129. if (expression != null)
  130. {
  131. return expression.getValue(FacesContext.getCurrentInstance()
  132. .getELContext());
  133. }
  134. return null;
  135. }
  136. public Object eval(Serializable key, Object defaultValue)
  137. {
  138. Object returnValue = _fullState.get(key);
  139. if (returnValue != null)
  140. {
  141. return returnValue;
  142. }
  143. ValueExpression expression = _target.getValueExpression(key
  144. .toString());
  145. if (expression != null)
  146. {
  147. return expression.getValue(FacesContext.getCurrentInstance()
  148. .getELContext());
  149. }
  150. return defaultValue;
  151. }
  152. public Object get(Serializable key)
  153. {
  154. return _fullState.get(key);
  155. }
  156. public Object put(Serializable key, Object value)
  157. {
  158. Object returnValue = null;
  159. if (_createDeltas())
  160. {
  161. if (_deltas.containsKey(key))
  162. {
  163. returnValue = _deltas.put(key, value);
  164. _fullState.put(key, value);
  165. }
  166. else
  167. {
  168. _deltas.put(key, value);
  169. returnValue = _fullState.put(key, value);
  170. }
  171. }
  172. else
  173. {
  174. /*
  175. if (value instanceof StateHolder)
  176. {
  177. _stateHolderKeys.add(key);
  178. }
  179. */
  180. returnValue = _fullState.put(key, value);
  181. }
  182. return returnValue;
  183. }
  184. public Object put(Serializable key, String mapKey, Object value)
  185. {
  186. boolean returnSet = false;
  187. Object returnValue = null;
  188. if (_createDeltas())
  189. {
  190. //Track delta case
  191. Map<String, Object> mapValues = (Map<String, Object>) _deltas
  192. .get(key);
  193. if (mapValues == null)
  194. {
  195. mapValues = new InternalMap<String, Object>();
  196. _deltas.put(key, mapValues);
  197. }
  198. if (mapValues.containsKey(mapKey))
  199. {
  200. returnValue = mapValues.put(mapKey, value);
  201. returnSet = true;
  202. }
  203. else
  204. {
  205. mapValues.put(mapKey, value);
  206. }
  207. }
  208. //Handle change on full map
  209. Map<String, Object> mapValues = (Map<String, Object>) _fullState
  210. .get(key);
  211. if (mapValues == null)
  212. {
  213. mapValues = new InternalMap<String, Object>();
  214. _fullState.put(key, mapValues);
  215. }
  216. if (returnSet)
  217. {
  218. mapValues.put(mapKey, value);
  219. }
  220. else
  221. {
  222. returnValue = mapValues.put(mapKey, value);
  223. }
  224. return returnValue;
  225. }
  226. public Object remove(Serializable key)
  227. {
  228. Object returnValue = null;
  229. if (_createDeltas())
  230. {
  231. if (_deltas.containsKey(key))
  232. {
  233. // Keep track of the removed values using key/null pair on the delta map
  234. returnValue = _deltas.put(key, null);
  235. _fullState.remove(key);
  236. }
  237. else
  238. {
  239. // Keep track of the removed values using key/null pair on the delta map
  240. _deltas.put(key, null);
  241. returnValue = _fullState.remove(key);
  242. }
  243. }
  244. else
  245. {
  246. returnValue = _fullState.remove(key);
  247. }
  248. return returnValue;
  249. }
  250. public Object remove(Serializable key, Object valueOrKey)
  251. {
  252. // Comment by lu4242 : The spec javadoc says if it is a Collection
  253. // or Map deal with it. But the intention of this method is work
  254. // with add(?,?) and put(?,?,?), this ones return instances of
  255. // InternalMap and InternalList to prevent mixing, so to be
  256. // consistent we'll cast to those classes here.
  257. Object collectionOrMap = _fullState.get(key);
  258. Object returnValue = null;
  259. if (collectionOrMap instanceof InternalMap)
  260. {
  261. if (_createDeltas())
  262. {
  263. returnValue = _removeValueOrKeyFromMap(_deltas, key,
  264. valueOrKey, true);
  265. _removeValueOrKeyFromMap(_fullState, key, valueOrKey, false);
  266. }
  267. else
  268. {
  269. returnValue = _removeValueOrKeyFromMap(_fullState, key,
  270. valueOrKey, false);
  271. }
  272. }
  273. else if (collectionOrMap instanceof InternalList)
  274. {
  275. if (_createDeltas())
  276. {
  277. returnValue = _removeValueOrKeyFromCollectionDelta(_deltas,
  278. key, valueOrKey);
  279. _removeValueOrKeyFromCollection(_fullState, key, valueOrKey);
  280. }
  281. else
  282. {
  283. returnValue = _removeValueOrKeyFromCollection(_fullState, key,
  284. valueOrKey);
  285. }
  286. }
  287. return returnValue;
  288. }
  289. private static Object _removeValueOrKeyFromCollectionDelta(
  290. Map<Serializable, Object> stateMap, Serializable key,
  291. Object valueOrKey)
  292. {
  293. Object returnValue = null;
  294. Map<Object, Boolean> c = (Map<Object, Boolean>) stateMap.get(key);
  295. if (c != null)
  296. {
  297. if (c.containsKey(valueOrKey))
  298. {
  299. returnValue = valueOrKey;
  300. }
  301. c.put(valueOrKey, Boolean.FALSE);
  302. }
  303. return returnValue;
  304. }
  305. private static Object _removeValueOrKeyFromCollection(
  306. Map<Serializable, Object> stateMap, Serializable key,
  307. Object valueOrKey)
  308. {
  309. Object returnValue = null;
  310. Collection c = (Collection) stateMap.get(key);
  311. if (c != null)
  312. {
  313. if (c.remove(valueOrKey))
  314. {
  315. returnValue = valueOrKey;
  316. }
  317. if (c.isEmpty())
  318. {
  319. stateMap.remove(key);
  320. }
  321. }
  322. return returnValue;
  323. }
  324. private static Object _removeValueOrKeyFromMap(
  325. Map<Serializable, Object> stateMap, Serializable key,
  326. Object valueOrKey, boolean delta)
  327. {
  328. if (valueOrKey == null)
  329. {
  330. return null;
  331. }
  332. Object returnValue = null;
  333. Map<String, Object> map = (Map<String, Object>) stateMap.get(key);
  334. if (map != null)
  335. {
  336. if (delta)
  337. {
  338. // Keep track of the removed values using key/null pair on the delta map
  339. returnValue = map.put((String) valueOrKey, null);
  340. }
  341. else
  342. {
  343. returnValue = map.remove(valueOrKey);
  344. }
  345. if (map.isEmpty())
  346. {
  347. //stateMap.remove(key);
  348. stateMap.put(key, null);
  349. }
  350. }
  351. return returnValue;
  352. }
  353. public boolean isTransient()
  354. {
  355. return _transient;
  356. }
  357. /**
  358. * Serializing cod
  359. * the serialized data structure consists of key value pairs unless the value itself is an internal array
  360. * or a map in case of an internal array or map the value itself is another array with its initial value
  361. * myfaces.InternalArray, myfaces.internalMap
  362. * <p/>
  363. * the internal Array is then mapped to another array
  364. * <p/>
  365. * the internal Map again is then mapped to a map with key value pairs
  366. */
  367. public Object saveState(FacesContext context)
  368. {
  369. Map serializableMap = (isInitialStateMarked()) ? _deltas : _fullState;
  370. if (serializableMap == null || serializableMap.size() == 0)
  371. {
  372. return null;
  373. }
  374. /*
  375. int stateHolderKeyCount = 0;
  376. if (isInitalStateMarked())
  377. {
  378. for (Iterator<Serializable> it = _stateHolderKeys.iterator(); it.hasNext();)
  379. {
  380. Serializable key = it.next();
  381. if (!_deltas.containsKey(key))
  382. {
  383. stateHolderKeyCount++;
  384. }
  385. }
  386. }*/
  387. Map.Entry<Serializable, Object> entry;
  388. //entry == key, value, key, value
  389. Object[] retArr = new Object[serializableMap.entrySet().size() * 2];
  390. //Object[] retArr = new Object[serializableMap.entrySet().size() * 2 + stateHolderKeyCount];
  391. Iterator<Map.Entry<Serializable, Object>> it = serializableMap.entrySet().iterator();
  392. int cnt = 0;
  393. while (it.hasNext())
  394. {
  395. entry = it.next();
  396. retArr[cnt] = entry.getKey();
  397. Object value = entry.getValue();
  398. // The condition in which the call to saveAttachedState
  399. // is to handle List, StateHolder or non Serializable instances.
  400. // we check it here, to prevent unnecessary calls.
  401. if (value instanceof StateHolder ||
  402. value instanceof List ||
  403. !(value instanceof Serializable))
  404. {
  405. Object savedValue = UIComponentBase.saveAttachedState(context,
  406. value);
  407. retArr[cnt + 1] = savedValue;
  408. }
  409. else
  410. {
  411. retArr[cnt + 1] = value;
  412. }
  413. cnt += 2;
  414. }
  415. /*
  416. if (isInitalStateMarked())
  417. {
  418. for (Iterator<Serializable> it2 = _stateHolderKeys.iterator(); it.hasNext();)
  419. {
  420. Serializable key = it2.next();
  421. if (!_deltas.containsKey(key))
  422. {
  423. retArr[cnt] = key;
  424. Object value = _fullState.get(key);
  425. if (value instanceof PartialStateHolder)
  426. {
  427. //Could contain delta, save it as _AttachedDeltaState
  428. PartialStateHolder holder = (PartialStateHolder) value;
  429. if (holder.isTransient())
  430. {
  431. retArr[cnt + 1] = null;
  432. }
  433. else
  434. {
  435. retArr[cnt + 1] = new _AttachedDeltaWrapper(value.getClass(), holder.saveState(context));
  436. }
  437. }
  438. else
  439. {
  440. //Save everything
  441. retArr[cnt + 1] = UIComponentBase.saveAttachedState(context, _fullState.get(key));
  442. }
  443. cnt += 2;
  444. }
  445. }
  446. }
  447. */
  448. return retArr;
  449. }
  450. public void restoreState(FacesContext context, Object state)
  451. {
  452. if (state == null)
  453. {
  454. return;
  455. }
  456. Object[] serializedState = (Object[]) state;
  457. for (int cnt = 0; cnt < serializedState.length; cnt += 2)
  458. {
  459. Serializable key = (Serializable) serializedState[cnt];
  460. Object savedValue = UIComponentBase.restoreAttachedState(context,
  461. serializedState[cnt + 1]);
  462. if (isInitialStateMarked())
  463. {
  464. if (savedValue instanceof InternalDeltaListMap)
  465. {
  466. for (Map.Entry<Object, Boolean> mapEntry : ((Map<Object, Boolean>) savedValue)
  467. .entrySet())
  468. {
  469. boolean addOrRemove = mapEntry.getValue();
  470. if (addOrRemove)
  471. {
  472. //add
  473. this.add(key, mapEntry.getKey());
  474. }
  475. else
  476. {
  477. //remove
  478. this.remove(key, mapEntry.getKey());
  479. }
  480. }
  481. }
  482. else if (savedValue instanceof InternalMap)
  483. {
  484. for (Map.Entry<String, Object> mapEntry : ((Map<String, Object>) savedValue)
  485. .entrySet())
  486. {
  487. this.put(key, mapEntry.getKey(), mapEntry.getValue());
  488. }
  489. }
  490. /*
  491. else if (savedValue instanceof _AttachedDeltaWrapper)
  492. {
  493. _AttachedStateWrapper wrapper = (_AttachedStateWrapper) savedValue;
  494. //Restore delta state
  495. ((PartialStateHolder)_fullState.get(key)).restoreState(context, wrapper.getWrappedStateObject());
  496. //Add this key as StateHolder key
  497. _stateHolderKeys.add(key);
  498. }
  499. */
  500. else
  501. {
  502. put(key, savedValue);
  503. }
  504. }
  505. else
  506. {
  507. put(key, savedValue);
  508. }
  509. }
  510. }
  511. public void setTransient(boolean transientValue)
  512. {
  513. _transient = transientValue;
  514. }
  515. //We use our own data structures just to make sure
  516. //nothing gets mixed up internally
  517. static class InternalMap<K, V> extends HashMap<K, V> implements StateHolder
  518. {
  519. public InternalMap()
  520. {
  521. super();
  522. }
  523. public InternalMap(int initialCapacity, float loadFactor)
  524. {
  525. super(initialCapacity, loadFactor);
  526. }
  527. public InternalMap(Map<? extends K, ? extends V> m)
  528. {
  529. super(m);
  530. }
  531. public InternalMap(int initialSize)
  532. {
  533. super(initialSize);
  534. }
  535. public boolean isTransient()
  536. {
  537. return false;
  538. }
  539. public void setTransient(boolean newTransientValue)
  540. {
  541. // No op
  542. }
  543. public void restoreState(FacesContext context, Object state)
  544. {
  545. Object[] listAsMap = (Object[]) state;
  546. for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
  547. {
  548. this.put((K) listAsMap[cnt], (V) UIComponentBase
  549. .restoreAttachedState(context, listAsMap[cnt + 1]));
  550. }
  551. }
  552. public Object saveState(FacesContext context)
  553. {
  554. int cnt = 0;
  555. Object[] mapArr = new Object[this.size() * 2];
  556. for (Map.Entry<K, V> entry : this.entrySet())
  557. {
  558. mapArr[cnt] = entry.getKey();
  559. Object value = entry.getValue();
  560. if (value instanceof StateHolder ||
  561. value instanceof List ||
  562. !(value instanceof Serializable))
  563. {
  564. mapArr[cnt + 1] = UIComponentBase.saveAttachedState(context, value);
  565. }
  566. else
  567. {
  568. mapArr[cnt + 1] = value;
  569. }
  570. cnt += 2;
  571. }
  572. return mapArr;
  573. }
  574. }
  575. /**
  576. * Map used to keep track of list changes
  577. */
  578. static class InternalDeltaListMap<K, V> extends InternalMap<K, V>
  579. {
  580. public InternalDeltaListMap()
  581. {
  582. super();
  583. }
  584. public InternalDeltaListMap(int initialCapacity, float loadFactor)
  585. {
  586. super(initialCapacity, loadFactor);
  587. }
  588. public InternalDeltaListMap(int initialSize)
  589. {
  590. super(initialSize);
  591. }
  592. public InternalDeltaListMap(Map<? extends K, ? extends V> m)
  593. {
  594. super(m);
  595. }
  596. }
  597. static class InternalList<T> extends ArrayList<T> implements StateHolder
  598. {
  599. public InternalList()
  600. {
  601. super();
  602. }
  603. public InternalList(Collection<? extends T> c)
  604. {
  605. super(c);
  606. }
  607. public InternalList(int initialSize)
  608. {
  609. super(initialSize);
  610. }
  611. public boolean isTransient()
  612. {
  613. return false;
  614. }
  615. public void setTransient(boolean newTransientValue)
  616. {
  617. }
  618. public void restoreState(FacesContext context, Object state)
  619. {
  620. Object[] listAsArr = (Object[]) state;
  621. //since all other options would mean dual iteration
  622. //we have to do it the hard way
  623. for (Object elem : listAsArr)
  624. {
  625. add((T) UIComponentBase.restoreAttachedState(context, elem));
  626. }
  627. }
  628. public Object saveState(FacesContext context)
  629. {
  630. Object[] values = new Object[size()];
  631. for (int i = 0; i < size(); i++)
  632. {
  633. Object value = get(i);
  634. if (value instanceof StateHolder ||
  635. value instanceof List ||
  636. !(value instanceof Serializable))
  637. {
  638. values[i] = UIComponentBase.saveAttachedState(context, value);
  639. }
  640. else
  641. {
  642. values[i] = value;
  643. }
  644. }
  645. return values;
  646. }
  647. }
  648. }