1    /*
2     * Copyright 2006 :torweg free software group
3     * 
4     * This program is free software: you can redistribute it and/or modify
5     * it under the terms of the GNU General Public License as published by
6     * the Free Software Foundation, either version 3 of the License, or
7     * (at your option) any later version.
8     * 
9     * This program is distributed in the hope that it will be useful,
10    * but WITHOUT ANY WARRANTY; without even the implied warranty of
11    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    * GNU General Public License for more details.
13    * 
14    * You should have received a copy of the GNU General Public License
15    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16    *
17    */
18   package org.torweg.pulse.site.content;
19   
20   import java.io.Serializable;
21   import java.util.List;
22   import java.util.Map;
23   
24   import javax.persistence.Basic;
25   import javax.persistence.CascadeType;
26   import javax.persistence.Column;
27   import javax.persistence.Entity;
28   import javax.persistence.ManyToOne;
29   import javax.xml.bind.annotation.XmlAccessOrder;
30   import javax.xml.bind.annotation.XmlAccessType;
31   import javax.xml.bind.annotation.XmlAccessorOrder;
32   import javax.xml.bind.annotation.XmlAccessorType;
33   import javax.xml.bind.annotation.XmlElement;
34   import javax.xml.bind.annotation.XmlRootElement;
35   
36   import net.sf.json.JSONObject;
37   
38   import org.jdom.Element;
39   import org.slf4j.Logger;
40   import org.slf4j.LoggerFactory;
41   import org.torweg.pulse.bundle.Bundle;
42   import org.torweg.pulse.bundle.JDOMable;
43   import org.torweg.pulse.invocation.lifecycle.Lifecycle;
44   import org.torweg.pulse.invocation.lifecycle.LifecycleException;
45   import org.torweg.pulse.service.request.ServiceRequest;
46   import org.torweg.pulse.util.INameable;
47   import org.torweg.pulse.util.entity.Node;
48   
49   /**
50    * a {@code AbstractRegistryNode} is an entry in the websites
51    * {@code ContentRegistry}.
52    * 
53    * @author Thomas Weber, Daniel Dietz
54    * @version $Revision: 1822 $
55    * @see ContentRegistry
56    */
57   @Entity
58   @XmlRootElement(name = "abstract-registry-node")
59   @XmlAccessorOrder(XmlAccessOrder.UNDEFINED)
60   @XmlAccessorType(XmlAccessType.FIELD)
61   public abstract class AbstractRegistryNode extends Node implements INameable,
62           JDOMable, Serializable {
63   
64       /**
65        * The serialVersionUID.
66        */
67       private static final long serialVersionUID = -857091009050712563L;
68   
69       /**
70        * the logger.
71        */
72       protected static final Logger LOGGER = LoggerFactory
73               .getLogger(AbstractRegistryNode.class);
74   
75       /**
76        * the name of the {@code AbstractRegistryNode}.
77        */
78       @Basic
79       @Column(nullable = false)
80       @XmlElement(name = "name")
81       private String name;
82   
83       /**
84        * the {@code Bundle} of the {@code RegistryBundleNode}.
85        */
86       @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH,
87               CascadeType.MERGE }, optional = false)
88       @XmlElement(name = "bundle")
89       private Bundle bundle;
90   
91       /**
92        * needed for Hibernate<sup>TM</sup>.
93        */
94       protected AbstractRegistryNode() {
95           super();
96       }
97   
98       /**
99        * @return returns the name of the {@code AbstractRegistryNode}.
100       */
101      public final String getName() {
102          return this.name;
103      }
104  
105      /**
106       * sets a new name for the {@code AbstractRegistryNode}.
107       * 
108       * @param n
109       *            the name to be set
110       */
111      public final void setName(final String n) {
112          this.name = n;
113      }
114  
115      /**
116       * sets the {@code Bundle} of the {@code RegistryBundleNode}.&nbsp;The name
117       * of the {@code RegistryBundleNode} is set to {@code Bundle#getName()}.
118       * 
119       * @param b
120       *            the {@code Bundle}
121       */
122      public void setBundle(final Bundle b) {
123          this.bundle = b;
124      }
125  
126      /**
127       * returns the {@code Bundle} of the {@code RegistryBundleNode}.
128       * 
129       * @return the {@code Bundle} of the {@code RegistryBundleNode}
130       */
131      public final Bundle getBundle() {
132          try {
133              /* make sure our bundle has initialised transient values */
134              this.bundle = Lifecycle.getBundle(this.bundle.getName());
135          } catch (LifecycleException e) {
136              LOGGER.error("Lifecycle is not running!", e);
137          }
138          return this.bundle;
139      }
140  
141      /**
142       * Adds a new {@code AbstractRegistryNode} to the children of this
143       * {@code AbstractRegistryNode} if {@code Locale}s match.
144       * 
145       * @param n
146       *            the {@code AbstractRegistryNode} to be added.
147       */
148      @Override
149      public void addChild(final Node n) {
150          AbstractRegistryNode tn = (AbstractRegistryNode) n;
151          super.addChild(tn);
152      }
153  
154      /**
155       * adds a new {@code AbstractRegistryNode} at a given position to the list
156       * children of this {@code AbstractRegistryNode} if {@code Locale}s match.
157       * 
158       * @param pos
159       *            the position in the list of children
160       * @param n
161       *            the {@code AbstractRegistryNode} to become a child of this
162       *            {@code AbstractRegistryNode}.
163       */
164      @Override
165      public void addChild(final int pos, final Node n) {
166          AbstractRegistryNode tn = (AbstractRegistryNode) n;
167          super.addChild(pos, tn);
168      }
169  
170      /**
171       * sets the children of the {@code AbstractRegistryNode} if {@code Locale}s
172       * match.
173       * 
174       * @param nodeList
175       *            the list of child {@code AbstractRegistryNode}s
176       * @param <E>
177       *            a class extending {@code Node}
178       */
179      @Override
180      @SuppressWarnings("unchecked")
181      public <E extends Node> void setChildren(final List<E> nodeList) {
182          super.setChildren((List<AbstractRegistryNode>) nodeList);
183      }
184  
185      /**
186       * Returns a child by name if exists.
187       * 
188       * @param n
189       *            the name to look for
190       * 
191       * @return an {@code AbstractRegistryNode} if found, {@code null} otherwise
192       */
193      public final AbstractRegistryNode getChildByName(final String n) {
194          for (Node node : getChildren()) {
195              AbstractRegistryNode arn = (AbstractRegistryNode) node;
196              if (arn.getName().equals(n)) {
197                  return arn;
198              }
199          }
200          return null;
201      }
202  
203      /**
204       * Returns a {@code StringBuilder} with the {@code ContentRegistry}-path of
205       * the {@code AbstractRegistryNode}.
206       * <tt>System.getProperty("file.separator")</tt> will be used as
207       * path-separator.
208       * 
209       * @return a {@code StringBuilder} with the {@code ContentRegistry}-path of
210       *         the {@code AbstractRegistryNode}
211       */
212      public final StringBuilder getPathBuilder() {
213          if (getParent() != null) {
214              return ((AbstractRegistryNode) getParent()).getPathBuilder()
215                      .append(System.getProperty("file.separator"))
216                      .append(getName());
217          }
218          return new StringBuilder(getName());
219      }
220  
221      /**
222       * returns a string with the disabled tree actions delimited by colons.
223       * 
224       * @return a string with the disabled tree actions delimited by colons
225       */
226      public abstract String getDisabledActions();
227  
228      /**
229       * returns a map of all the possible actions and their corresponding URLs
230       * for the {@code AbstractRegistryNode}.
231       * 
232       * @param req
233       *            the current request
234       * @return a map of all the possible actions and their corresponding URLs
235       *         for the {@code AbstractRegistryNode}
236       */
237      public abstract Map<String, String> getActionURLs(final ServiceRequest req);
238  
239      /**
240       * calls {@link AbstractRegistryNode#deserializeToJDOM(ServiceRequest)} with
241       * {@code null}.
242       * 
243       * @return the {@code AbstractRegistryNode} as an {@code Element}
244       */
245      public final Element deserializeToJDOM() {
246          return deserializeToJDOM(null);
247      }
248  
249      /**
250       * @param request
251       *            the current request
252       * @return the {@code AbstractRegistryNode} as an {@code Element}
253       */
254      public abstract Element deserializeToJDOM(ServiceRequest request);
255  
256      /**
257       * /** returns a {@code JSONObject} representation of the
258       * {@code AbstractRegistryNode}.
259       * 
260       * @return a {@code JSONObject} representation of the
261       *         {@code AbstractRegistryNode}
262       */
263      @Override
264      public JSONObject toJSON() {
265          JSONObject nodeObject = super.toJSON();
266          nodeObject.put("text", getName());
267          nodeObject.put("uiProvider", "RegistryTreeNodeUI");
268          nodeObject.put("bundle", getBundle().getName());
269          return nodeObject;
270      }
271  
272  }
273