View Javadoc

1   /* This file is part of COPAL (COntext Provisioning for All).
2    *
3    * COPAL is a part of SM4All (Smart hoMes for All) project.
4    *
5    * COPAL is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * COPAL is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with COPAL. If not, see <http://www.gnu.org/licenses/>.
17   */
18  package at.ac.tuwien.infosys.sm4all.copal.api.xml;
19  
20  import org.w3c.dom.Element;
21  import at.ac.tuwien.infosys.sm4all.copal.api.util.MissingFieldException;
22  import static at.ac.tuwien.infosys.sm4all.copal.api.xml.Base.getChildElement;
23  
24  /**
25   * Strategy class for inserting one {@link Element} before another
26   * {@link Element}.
27   * 
28   * @author sanjin
29   */
30  public class InsertBefore implements AddStrategy {
31  
32      private final String siblingName;
33      private final AddStrategy onFailStrategy;
34  
35      /**
36       * Creates instance of insert-before {@link AddStrategy} that will insert
37       * {@link Element}s before an {@link Element} with specified local name. If
38       * such {@link Element} cannot be found then the specified on-fail
39       * {@link AddStrategy} is called.
40       * 
41       * @param siblingName the local name of the sibling {@link Element}.
42       * @param onFailStrategy the on-fail {@link AddStrategy}.
43       * @throws NullPointerException if specified sibling name or on-fail
44       *         {@link AddStrategy} is <code>null</code>.
45       * @throws IllegalArgumentException if specified sibling name is an empty or
46       *         blank string.
47       */
48      public InsertBefore(final String siblingName,
49              final AddStrategy onFailStrategy) {
50          super();
51  
52          if (siblingName == null)
53              throw new NullPointerException("Sibling name cannot be null.");
54          if (siblingName.trim().isEmpty())
55              throw new IllegalArgumentException(
56                      "Sibling name cannot be an empty or blank string.");
57          if (onFailStrategy == null)
58              throw new NullPointerException(
59                      "On-fail add strategy cannot be null.");
60  
61          this.siblingName = siblingName;
62          this.onFailStrategy = onFailStrategy;
63      }
64  
65      /**
66       * Inserts specified child {@link Element} into specified parent
67       * {@link Element} before an {@link Element} with specified namespace URI
68       * and local name. If such {@link Element} cannot be found then the
69       * specified on-fail {@link AddStrategy} is called.
70       * 
71       * @param parent the parent {@link Element}.
72       * @param child the child {@link Element}.
73       * @throws NullPointerException if parent or child {@link Element} is
74       *         <code>null</code>.
75       */
76      @Override
77      public void add(final Element parent, final Element child) {
78          if (parent == null)
79              throw new NullPointerException("Parent cannot be null.");
80          if (child == null)
81              throw new NullPointerException("Child cannot be null.");
82  
83          try {
84              final Element sibling = getChildElement(parent, this.siblingName);
85              parent.insertBefore(child, sibling);
86          } catch (final MissingFieldException ex) {
87              this.onFailStrategy.add(parent, child);
88          }
89      }
90  }