Source code: com/RuntimeCollective/sitemap/bean/SiteLocationLink.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/sitemap/bean/SiteLocationLink.java,v 1.26 2003/09/30 15:12:59 joe Exp $
2 * $Revision: 1.26 $
3 * $Date: 2003/09/30 15:12:59 $
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.sitemap.bean;
31
32 import com.RuntimeCollective.content.bean.Link;
33 import com.RuntimeCollective.content.bean.File;
34 import com.RuntimeCollective.sitemap.SitemapException;
35 import com.RuntimeCollective.sitemap.bean.ContentSiteLocation;
36 import com.RuntimeCollective.sitemap.bean.SiteLocation;
37 import com.RuntimeCollective.sitemap.bean.SiteNode;
38
39 import com.RuntimeCollective.webapps.EntityBeanStore;
40 import com.RuntimeCollective.webapps.RuntimeDataSource;
41 import com.RuntimeCollective.webapps.RuntimeParameters;
42 import com.RuntimeCollective.webapps.bean.EntityBean;
43 import com.RuntimeCollective.webapps.bean.User;
44 import com.RuntimeCollective.webapps.bean.DateBean;
45 import com.RuntimeCollective.webapps.bean.Versioned;
46
47 import java.net.MalformedURLException;
48 import java.net.URL;
49 import java.sql.SQLException;
50 import java.util.ArrayList;
51 import java.util.Iterator;
52 import java.util.Vector;
53
54 /**
55 * The SiteLocationLink class implements the abstract Link class, by
56 * linking to a SiteLocation.
57 *
58 * NB: Saving a SLL doesn't save its SiteLocation, as that could provoke
59 * some infinite loop. So take care of saving the destination first.
60 *
61 * @version $Id: SiteLocationLink.java,v 1.26 2003/09/30 15:12:59 joe Exp $
62 */
63 public class SiteLocationLink extends Link {
64
65 // ---Inherited from EntityBean---------------------------
66
67 /** The name of the database table for this bean type. */
68 public static final String DATABASE_TABLE = "sitemap_sllink";
69
70 /** Save this SiteLocationLink to the database.
71 * @exception SQLException is thrown if the object couldn't be saved properly to the database.
72 */
73 public void save() throws SQLException {
74
75 String dbalias = RuntimeDataSource.getDefaultAlias();
76
77 // Save the SiteLocationLink's Link attributes
78 super.save();
79
80 // Save the SiteLocation
81 // not anymore, this can make an infinite loop if the link points to a parent
82 // of the node it belongs to
83 //if (SiteLocationId != -1)
84 //RuntimeParameters.getStore().save("com.RuntimeCollective.sitemap.bean.SiteLocation", SiteLocationId);
85
86 // Save the SiteLocationLink's basic attributes
87 String sl_id = null;
88 if (SiteLocationId != -1)
89 sl_id = ""+SiteLocationId;
90
91 RuntimeDataSource.save( id, "sitemap_sllink", new String[] { "sitelocation_id" }, new Object[] { sl_id } );
92 }
93
94 /** Delete this SiteLocationLink from the database.
95 * @exception SQLException is thrown if the object couldn't be deleted properly from the database.
96 */
97 public void delete() throws SQLException {
98
99 String[] updates;
100 EntityBeanStore ebs = RuntimeParameters.getStore();
101 ContentSiteLocation CSL;
102
103 // we have to tell all ContentSiteLocations to forget about this Link
104 try {
105
106 // that was the old way, which loads every CSL - can be extremelly slow
107 // Iterator CSLs = ebs.getAll("com.RuntimeCollective.sitemap.bean.ContentSiteLocation");
108 // ContentSiteLocation CSL;
109 // while (CSLs.hasNext()) {
110 // CSL = (ContentSiteLocation) CSLs.next();
111
112 // now we do just the one query in the db
113 int[] CSLIds = RuntimeDataSource.queryInts("select cont_site_loc_id from "+ContentSiteLocation.SITEMAP_CONTENT_MAP+" where content_id = "+getId());
114 for (int i=0; i<CSLIds.length; i++) {
115 CSL = (ContentSiteLocation) ebs.get("com.RuntimeCollective.sitemap.bean.ContentSiteLocation", CSLIds[i]);
116 if (CSL.removeSubContent(this)) {
117 ebs.save(CSL);
118 }
119 }
120
121 } catch (SQLException e) {
122 throw new SitemapException("SiteLocationLink.delete() had a problem when telling CSLs to forget about this link : "+e);
123 }
124
125 updates = new String[] { "delete from sitemap_sllink where id = "+id };
126 RuntimeDataSource.update( updates);
127
128 super.delete();
129 }
130
131
132 //---Specific to Link---------------------
133
134 /** Is this link displayable, ie is it valid (using the Live version of the SiteLocation if it exists).
135 * @return a boolean
136 */
137 public boolean isDisplayable() {
138 return isDisplayable(true);
139 }
140
141 /** Is this link displayable, ie is it valid (using or not the Live version of the SiteLocation).
142 * <p>
143 * If useLive is false, use the SiteLocation this object really refers to.
144 * <br>
145 * If useLive is true, use the Live version of the SiteLocation (if it exists, otherwise, the SiteLocation itself).
146 *
147 * @param useLive, a boolean
148 * @return a boolean
149 */
150 public boolean isDisplayable(boolean useLive) {
151
152 // check if the SiteLocation is defined and live
153 if ((SiteLocationId != -1) && (getSiteLocation() != null)) {
154 SiteLocation sl = getSiteLocation();
155 if ((useLive) && (sl instanceof Versioned)) {
156 SiteLocation live = (SiteLocation) ((Versioned) sl).getVersion(Versioned.LIVE_TAG);
157 if (live != null)
158 sl = live;
159 }
160 return sl.isLive();
161
162 } else {
163 return false;
164 }
165 }
166
167 public static String PREVIEW_PAGE_PARAM = "FORWARDnavPreviewPage";
168 public static String VIEW_PAGE_PARAM = "FORWARDnavViewPage";
169 public static String PREVIEW_PAGE_DEFAULT = "/admin/previewPage.jsp";
170 public static String VIEW_PAGE_DEFAULT = "/viewPage.jsp";
171 public static String ID_PARAM = "?id=";
172
173 /** Get the LinkURL: a link to viewPage (if the link isDisplayable) or previewPage (otherwise).
174 * For plain users, you should check if the link is displayable before calling this.
175 *
176 * @param The URL to link to
177 */
178 public URL getLinkURL() {
179 if (SiteLocationId != -1) {
180 try {
181 StringBuffer sb = (new StringBuffer(80)).append("http://").append(RuntimeParameters.get("pageRoot"));
182 // if the SL is live, link to it, otherwise link to its preview
183 // FR: was getSiteLocation().isLive()
184 String stub = null;
185 if (isDisplayable()) {
186 try {
187 stub = RuntimeParameters.get(VIEW_PAGE_PARAM);
188 } catch (Exception e) {
189 // no param set, use the old/legacy value
190 stub = VIEW_PAGE_DEFAULT;
191 }
192
193 } else {
194 try {
195 stub = RuntimeParameters.get(PREVIEW_PAGE_PARAM);
196 } catch (Exception e) {
197 // no param set, use the old/legacy value
198 stub = PREVIEW_PAGE_DEFAULT;
199 }
200 }
201
202 sb.append(stub).append(ID_PARAM).append(SiteLocationId);
203
204 return new URL(sb.toString());
205
206 } catch (MalformedURLException e) {
207 RuntimeParameters.logDebug(this, "Couldn't generate URL for SiteLocationLink "+getId()+" on SiteLocation "+SiteLocationId);
208 return null;
209 }
210
211 } else {
212 RuntimeParameters.logDebug(this, "Couldn't generate URL for SiteLocationLink "+getId()+", SiteLocation is not defined yet.");
213 return null;
214 }
215 }
216
217 public static String NOTHING = "";
218
219 /** Get the LinkText: for a SiteLocationLink, this uses the SiteLocation's Name or SectionName.
220 * @return The text which will be clickable
221 */
222 public String getLinkText() {
223 if (SiteLocationId != -1) {
224 // if it's a channel or a subsection, use the SectionName (live version, if available)
225 SiteLocation siteLocation = getSiteLocation(Versioned.LIVE_TAG);
226 if (siteLocation != null) {
227 if ((siteLocation instanceof SiteNode) && (((SiteNode) siteLocation).getDepthInSitemap() < 3)) {
228 return ((SiteNode) siteLocation).getSectionName();
229 } else {
230 return siteLocation.getName();
231 }
232 }
233 }
234
235 return NOTHING;
236 }
237
238 /** Get the OpenInNewWindow: redefine to take into account the template of the SiteLocation
239 * @return A boolean, yes or no
240 */
241 public boolean getOpenInNewWindow() {
242 return (super.getOpenInNewWindow() || ((getSiteLocation()!=null) && (getSiteLocation().getTheTemplate()!=null) && (getSiteLocation().getTheTemplate().getLinkToNewWindow())));
243 }
244
245
246 //---Specific to SiteLocationLink---------------------
247
248
249 /** Does this SiteLocationLink link to a SiteLocation, and then which one ? */
250 protected int SiteLocationId;
251
252 /** Set the SiteLocation.
253 * @param siteLocation, a SiteLocation
254 */
255 public void setSiteLocation(SiteLocation siteLocation) {
256 if (siteLocation != null)
257 SiteLocationId = siteLocation.getId();
258 else
259 SiteLocationId = -1;
260 }
261
262 /** Get the SiteLocation, the trunk version of it if it exists.
263 * @return A SiteLocation
264 */
265 public SiteLocation getSiteLocation() {
266 return getSiteLocation(Versioned.TRUNK_TAG);
267 }
268
269 /** Get the SiteLocation, possibly checking a particular version.
270 * <p>
271 * If useVersion is null, return the SiteLocation this object really refers to.
272 * <br>
273 * Otherwise, return the specified version of this object, if there is one. If there isn't, then use this version.
274 *
275 * @param useVersion an alternative version to use, if available
276 * @return A SiteLocation
277 */
278 public SiteLocation getSiteLocation(String useVersion) {
279 if (SiteLocationId != -1) {
280 SiteLocation sl = (SiteLocation) RuntimeParameters.getStore().get("com.RuntimeCollective.sitemap.bean.SiteLocation", SiteLocationId);
281 if (sl instanceof Versioned) {
282 SiteLocation version = (SiteLocation) ((Versioned) sl).getVersion(useVersion);
283 if (version != null)
284 return version;
285 }
286 return sl;
287
288 } else
289 return null;
290 }
291
292 /** Get the SiteLocation's Id.
293 * This is necessary, for a reason too long to explain.
294 * @return An int
295 */
296 public int getSiteLocationId() {
297 return SiteLocationId;
298 }
299
300
301
302
303
304 /** Construct a new blank SiteLocationLink, giving it a new unique ID.
305 * @exception SQLException is thrown if a new ID cannot be created.
306 */
307 public SiteLocationLink() throws SQLException {
308
309 super();
310
311 setSiteLocation(null);
312 }
313
314 /** Get a SiteLocationLink from the database, given an id.
315 * @param id ID of the SiteLocationLink.
316 * @exception SQLException is thrown if no such SiteLocationLink exists.
317 */
318 public SiteLocationLink(int id) throws SQLException {
319
320 super(id);
321
322
323 String dbalias = RuntimeDataSource.getDefaultAlias();
324
325 Object[] result = RuntimeDataSource.queryRow("select sll.sitelocation_id from sitemap_sllink sll where sll.id = "+id);
326 if (result.length != 1) {
327 throw new SQLException("Cannot load SiteLocationLink "+id+": "+result.length+" fields found in sitemap_sllink instead of 1.");
328 }
329
330 if (result[0] != null)
331 SiteLocationId = Integer.parseInt(result[0].toString());
332 else
333 SiteLocationId = -1;
334 }
335
336 /** Close the link and conditionally add the file type, if this is a link to the file type
337 * template (in this case it is called the pdf template but is used for other file types
338 * aswell) and whether or not it opens in a new window info
339 * @return a String that closes the link and adds any of the extra info
340 */
341 public String getLinkCloseTag() {
342
343 //RuntimeParameters.logDebug(this, "[SiteLocationLink] getSiteLocation().getTheTemplate().getName() returns "+getSiteLocation().getTheTemplate().getName());
344
345 // Are we linking to a "PDF File" page
346 // this is a hack for the SE enhancements
347 SiteLocation siteLocation = getSiteLocation();
348 if ((siteLocation != null) && (siteLocation.getTheTemplate() != null) && (PDFDOCUMENT.equals(siteLocation.getTheTemplate().getName()))) {
349
350 //RuntimeParameters.logDebug(this, "[SiteLocationLink] yes it is a pdf - the first if loop is true");
351 // we are using the template for pdf (or .docs .xl or any acceptable loadable file)
352 StringBuffer close = new StringBuffer().append(closeTag);
353 SiteNode node = (SiteNode) siteLocation;
354 File file = (File) node.getSubContent("pdffile",0);
355 String fileEnding = file.getFileEnding();
356
357 close.append("<br>(<i>.");
358 close.append(fileEnding);
359
360 if (getOpenInNewWindow()) {
361 close.append(" - opens in a new window )</i>");
362 } else {
363 close.append(")</i>");
364 }
365
366 if (fileEnding.equalsIgnoreCase("pdf")) {
367 close.append("<br><a href=\"http://www.adobe.com/products/acrobat\" target=\"_adobe\"><img border=\"0\" src=\"/templates/graphics/getacro.gif\"></a>");
368 }
369
370 return close.toString();
371
372 } else {
373 // as normal
374 return super.getLinkCloseTag();
375 }
376 }
377
378 protected static String PDFDOCUMENT = "PDF Document";
379
380 protected static String closeTag = "</a>";
381 }
382
383
384
385