Source code: com/RuntimeCollective/content/bean/ComplexContent.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/content/bean/ComplexContent.java,v 1.11 2003/09/30 15:12:46 joe Exp $
2 * $Revision: 1.11 $
3 * $Date: 2003/09/30 15:12:46 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.content.bean;
31
32 import com.RuntimeCollective.webapps.EntityBeanStore;
33 import com.RuntimeCollective.webapps.RuntimeParameters;
34 import com.RuntimeCollective.webapps.RuntimeDataSource;
35
36 import com.RuntimeCollective.content.ContentException;
37
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.Iterator;
41 import java.util.Vector;
42 import java.util.Collection;
43
44 import java.sql.SQLException;
45
46 /**
47 * A piece of content made up of one or more pieces of subcontent.
48 * @version $Id: ComplexContent.java,v 1.11 2003/09/30 15:12:46 joe Exp $
49 */
50 public class ComplexContent extends SimpleContent {
51
52 /** The default size of the subcontent arrays */
53 private static final int DEFAULT_ARRAY_SIZE = 10;
54
55 // == EntityBean methods ==================================
56
57 /** The name of the database table for this bean type. */
58 public static final String DATABASE_TABLE = "content_complex";
59
60 /** Save this bean to the database. */
61 public void save() {
62
63 try {
64
65 // save SimpleContent data
66 super.save();
67
68 String dbalias = RuntimeDataSource.getDefaultAlias();
69 EntityBeanStore ebs = RuntimeParameters.getStore();
70
71 // save ComplexContent data
72 RuntimeDataSource.save(id, "content_complex", new String[] { }, new Object[] { } );
73
74 // clear the existing SubContent mappings
75 RuntimeDataSource.update(new String[] { "delete from content_complex_subcontent_map where complex_content_id = "+this.id } );
76
77 // make the new mappings
78 Vector updates = new Vector();
79 String[] updates_array;
80 Iterator roles = getRoles();
81 Vector contents;
82 String role;
83 Content content;
84 int contentId;
85
86 while (roles.hasNext()) {
87 role = (String) roles.next();
88 contents = (Vector) iSubContents.get( role );
89
90 for (int position=0; position<contents.size(); position++ ) {
91 content = (Content) contents.get(position);
92 contentId = content.getId();
93
94 // save the SubContent
95 ebs.save("com.RuntimeCollective.content.bean.Content", contentId);
96
97 // make the new mapping
98 updates.add((new StringBuffer(40)).append("insert into content_complex_subcontent_map (complex_content_id, subcontent_id, role, position_no) values (").append(this.id).append(" ,").append(contentId).append(", '").append(role).append("', ").append(position).append(")").toString());
99
100 }
101 }
102
103 // A Vector has been used as a dynamic array. This just
104 // converts the Vector into an array for processing.
105 //
106 // Note: toArray could of been used here.
107 if (!updates.isEmpty()) {
108 updates_array = new String[updates.size()];
109 for (int i=0; i<updates.size(); i++)
110 updates_array[i] = (String) updates.get(i);
111 RuntimeDataSource.update(dbalias, updates_array);
112 }
113
114 } catch (SQLException e) {
115 RuntimeParameters.logError( this, "ComplexContent could not save() : ",e);
116 throw new ContentException("ComplexContent could not save() : "+e);
117 }
118 }
119
120
121 /** Delete this bean from the database. */
122 public void delete() {
123 try {
124 String[] updates;
125
126 // delete ContentSiteLocation specific data
127 updates = new String[] { "delete from content_complex_subcontent_map where complex_content_id = "+this.id, "delete from content_complex where id = "+this.id };
128 RuntimeDataSource.update(updates);
129
130 // delete SimpleContent data
131 super.delete();
132
133 } catch (SQLException e) {
134 RuntimeParameters.logError( this, "ComplexContent could not delete() : ",e);
135 throw new ContentException("ComplexContent could not delete() : "+e);
136 }
137
138 }
139
140
141
142
143 // == Subcontents methods ========================================
144
145 /** The SubContents */
146 protected HashMap iSubContents = new HashMap();
147
148 /** Get all Roles for which SubContents are defined at the moment. */
149 public Iterator getRoles() {
150 return iSubContents.keySet().iterator();
151 }
152
153 /** Set one SubContent in this ComplexContent, under a given role and position
154 * @param role, A String defining the role of the SubContent
155 * @param position, The position to set the SubContent in, from 0 to n
156 * @param content, a Content
157 */
158 public void setSubContent(String role, int position, Content subContent) {
159 Vector vSubContents = getSubContentsVector( role );
160 vSubContents.setElementAt( subContent, position );
161 }
162
163 /** Insert one SubContent in this ComplexContent, under a given role and position.
164 * If there is already a subcontent in this position then its position will be incremented recursively.
165 * If this position is greater than the current length of the subcontents in this role, then the new sub content will be added to the end.
166 * @param role, A String defining the role of the SubContent
167 * @param position, The position to set the SubContent in, from 0 to n
168 * @param content, a Content
169 */
170 public void insertSubContent(String role, int position, Content subContent) {
171 Vector vSubContents = getSubContentsVector( role );
172 if ( position >= vSubContents.size() ) vSubContents.add( subContent );
173 else vSubContents.insertElementAt( subContent, position );
174 }
175
176
177 /** Get one SubContent from this ComplexContent
178 * @param role, The role to look into
179 * @param position, The position where the SubContent is, from 0 to n
180 * @return The SubContent, or null if there is none for this position
181 */
182 public Content getSubContent(String role, int position) {
183 Vector vSubContents = getSubContentsVector( role );
184 return (Content) vSubContents.get( position );
185 }
186
187 /** Get all the SubContents from this ComplexContent for a given role, and without their positions
188 * @param role, a String defining the role to look into
189 * @return An Iterator of Content
190 */
191 public Iterator getSubContents(String role) {
192 Vector vSubContents = getSubContentsVector( role );
193 return vSubContents.iterator();
194 }
195
196
197 /** Remove a SubContent from this ComplexContent under a given role, and in all its positions (if more than one)
198 * @param role, a String defining the role to look into
199 * @param content, the Content to be removed
200 */
201 public void removeSubContent(String role, Content content) {
202 Vector vSubContents = getSubContentsVector( role );
203 while ( vSubContents.indexOf( content )>-1 ) vSubContents.remove( content );
204 }
205
206
207 /** Add a SubContent to this ComplexContent under a given role, at the current max position + 1
208 * @param role, a String defining the role to look into
209 * @param subContent, the SubContent to be added
210 */
211 public void addSubContent(String role, Content content) {
212 Vector vSubContents = getSubContentsVector( role );
213 vSubContents.add( content );
214 }
215
216 /** Get the position of this subcontent.
217 * If there is more than one occurence then return the first.
218 * If this content does not contain this subcontent, then -1 is return.
219 */
220 public int getPositionOfSubContent( String role, Content content ) {
221 Vector vSubContents = getSubContentsVector( role );
222 return vSubContents.indexOf( content );
223 }
224
225 /** Get the subcontents for the given role. If none is found then a new one is constructed. */
226 private Vector getSubContentsVector( String role ) {
227 Vector vSubContents = (Vector) iSubContents.get( role );
228 if ( vSubContents==null ) {
229 vSubContents = new Vector();
230 iSubContents.put( role, vSubContents );
231 }
232 return vSubContents;
233 }
234
235 // == Constructors =====================================================
236
237 /** Construct a new blank ComplexContent, giving it a new unique ID. */
238 public ComplexContent() throws SQLException {
239 // initialise a SimpleContent
240 super();
241 }
242
243 /** Get a current ComplexContent from the RuntimeDataSource, given an id.
244 * @param id ID of the ComplexContent.
245 * @exception SQLException is thrown if no such ComplexContent exists.
246 */
247 public ComplexContent(int id) throws SQLException {
248
249 // load a Content
250 super(id);
251
252 try {
253
254 String dbalias = RuntimeDataSource.getDefaultAlias();
255 Object[] result;
256
257 // load the SubContents
258 Object[][] rows = RuntimeDataSource.queryRows(dbalias, "select role, position_no, subcontent_id from content_complex_subcontent_map where complex_content_id = "+id+" order by position_no");
259
260 String role;
261 int position_no;
262 int content_id;
263 EntityBeanStore store = RuntimeParameters.getStore();
264
265 for (int i=0; i<rows.length; i++) {
266 role = (String) rows[i][0];
267 position_no = Integer.parseInt(rows[i][1].toString());
268 content_id = Integer.parseInt(rows[i][2].toString());
269 getSubContentsVector(role).add( (Content) store.get( "com.RuntimeCollective.content.bean.Content", content_id ) );
270 }
271
272 } catch (Exception e) {
273 throw new ContentException(e);
274 }
275 }
276 }
277
278