001: /*
002: * (C) Copyright 2000 - 2006 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019: package com.nabhinc.portal.model;
020:
021: import java.io.ByteArrayOutputStream;
022: import java.io.FileInputStream;
023: import java.io.StringReader;
024: import java.rmi.RemoteException;
025: import java.util.Calendar;
026: import java.util.Vector;
027:
028: import javax.servlet.ServletException;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.xml.bind.JAXBContext;
031: import javax.xml.bind.Marshaller;
032: import javax.xml.bind.Unmarshaller;
033: import javax.xml.bind.annotation.XmlAttribute;
034: import javax.xml.bind.annotation.XmlElement;
035: import javax.xml.bind.annotation.XmlRootElement;
036: import javax.xml.bind.annotation.XmlTransient;
037:
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: import com.nabhinc.core.Ownable;
042: import com.nabhinc.portal.api.PortalInformationStoreLocator;
043: import com.nabhinc.portal.api.VersionInfo;
044: import com.nabhinc.portal.core.ClientInfo;
045: import com.nabhinc.portal.spi.UserAdminServiceLocator;
046: import com.nabhinc.util.StringUtil;
047:
048: /**
049: *
050: *
051: * @author Padmanabh Dabke
052: * (c) 2006 Nabh Information Systems, Inc. All Rights Reserved.
053: */
054: @XmlRootElement(name="portal-application")
055: public class PortalApplication extends BaseProtectable implements
056: Ownable, Protectable {
057:
058: private static final long serialVersionUID = 2078671675732097944L;
059:
060: private transient Log paLogger = LogFactory.getLog(this .getClass());
061:
062: @XmlAttribute(name="path")
063: private String paPath = null;
064:
065: @XmlAttribute(name="owner")
066: private String paOwnerName = null;
067:
068: private transient long paOwnerId = -1;
069:
070: @XmlElement(name="created-by")
071: private String paCreatedBy = null;
072:
073: @XmlElement(name="creation-time")
074: private Calendar paCreationTime = null;
075:
076: @XmlElement(name="creation-ip")
077: private String paCreationIP = null;
078:
079: @XmlElement(name="page")
080: public PortalPage[] paPages = new PortalPage[0];
081:
082: @XmlElement(name="title")
083: private String paTitle = "";
084:
085: @XmlElement(name="tagline")
086: private String paTagline = "";
087:
088: @XmlElement(name="keywords")
089: private String paKeywords = null;
090:
091: @XmlAttribute(name="theme")
092: private String paTheme = "default";
093:
094: @XmlElement(name="logo")
095: private String paLogo = null;
096:
097: @XmlElement(name="header-style")
098: private String paHeaderStyle = "";
099:
100: @XmlElement(name="display-title")
101: private boolean paDisplayTitle = true;
102:
103: @XmlElement(name="version-info")
104: private VersionInfo paVersionInfo = null;
105:
106: @XmlElement(name="timezone")
107: private String timezone = null;
108:
109: @XmlTransient
110: private String paLockedBy = null;
111:
112: private String paIdPrefix = null;
113:
114: private String paLogoImage = "";
115:
116: private boolean paStale = false;
117:
118: /**
119: * Counter used to generate unique ids for portlet
120: * windows belonging to this portal application.
121: */
122:
123: private int paIdCounter = 1;
124:
125: private int paPageIdCounter = -1;
126:
127: private transient DisplayInfo paDisplayInfo = null;
128:
129: @XmlTransient
130: public boolean isStale() {
131: return paStale;
132: }
133:
134: public void setStale(boolean flag) {
135: this .paStale = flag;
136: }
137:
138: @XmlTransient
139: public String getLogoImage() {
140: return this .paLogoImage;
141: }
142:
143: private void computeLogoImage() {
144: if (StringUtil.isNotNullOrEmpty(this .paLogo)) {
145: this .paLogoImage = "<img class=\"SBPsiteLogo\" src=\""
146: + this .paLogo + "\"/>";
147: } else {
148: this .paLogoImage = "";
149: }
150: }
151:
152: @XmlTransient
153: public boolean isDisplayTitle() {
154: return this .paDisplayTitle;
155: }
156:
157: public void setDisplayTitle(boolean flag) {
158: this .paDisplayTitle = flag;
159: }
160:
161: @XmlTransient
162: public String getLogo() {
163: return this .paLogo;
164: }
165:
166: public void setLogo(String flag) {
167: this .paLogo = flag;
168: computeLogoImage();
169: }
170:
171: @XmlTransient
172: public String getHeaderStyle() {
173: return this .paHeaderStyle;
174: }
175:
176: public void setHeaderStyle(String flag) {
177: this .paHeaderStyle = flag;
178: }
179:
180: @XmlTransient
181: public String getPath() {
182: return this .paPath;
183: }
184:
185: public void setPath(String n) {
186: this .paPath = n;
187: this .paIdPrefix = "sb" + n.replaceAll("/", "_") + "_";
188: for (int i = 0; i < this .paPages.length; i++) {
189: PortalPage p = this .paPages[i];
190: p.setIdPrefix(this .paIdPrefix);
191: }
192: }
193:
194: @XmlTransient
195: public String getOwnerName() {
196: return this .paOwnerName;
197: }
198:
199: public void setOwnerName(String n) {
200: this .paOwnerName = n;
201: }
202:
203: @XmlTransient
204: public String getCreatedBy() {
205: return this .paCreatedBy;
206: }
207:
208: public void setCreatedBy(String n) {
209: this .paCreatedBy = n;
210: }
211:
212: @XmlTransient
213: public String getCreationIP() {
214: return this .paCreationIP;
215: }
216:
217: public void setCreationIP(String n) {
218: this .paCreationIP = n;
219: }
220:
221: @XmlTransient
222: public Calendar getCreationTime() {
223: return this .paCreationTime;
224: }
225:
226: public void setCreationTime(Calendar n) {
227: this .paCreationTime = n;
228: }
229:
230: @XmlTransient
231: public long getOwnerId() {
232: return this .paOwnerId;
233: }
234:
235: public void setOwnerId(long n) {
236: this .paOwnerId = n;
237: }
238:
239: @XmlTransient
240: public String getTagline() {
241: return this .paTagline;
242: }
243:
244: public void setTagline(String t) {
245: this .paTagline = t;
246: }
247:
248: @XmlTransient
249: public String getTitle() {
250: return this .paTitle;
251: }
252:
253: public void setTitle(String t) {
254: this .paTitle = t;
255: }
256:
257: @XmlTransient
258: public String getKeywords() {
259: return this .paKeywords;
260: }
261:
262: public void setKeywords(String t) {
263: this .paKeywords = t;
264: }
265:
266: @XmlTransient
267: public String getLockedBy() {
268: return this .paLockedBy;
269: }
270:
271: public void setLockedBy(String t) {
272: this .paLockedBy = t;
273: }
274:
275: @XmlTransient
276: public String getTheme() {
277: return this .paTheme;
278: }
279:
280: public void setTheme(String t) {
281: this .paTheme = t;
282: }
283:
284: /**
285: * Returns Timezone ID
286: * @return String representing the timezone ID.
287: */
288: @XmlTransient
289: public String getTimezone() {
290: return timezone;
291: }
292:
293: public void setTimezone(String timezone) {
294: this .timezone = timezone;
295: }
296:
297: @XmlTransient
298: public VersionInfo getVersionInfo() {
299: return this .paVersionInfo;
300: }
301:
302: public void setVersionInfo(VersionInfo t) {
303: this .paVersionInfo = t;
304: }
305:
306: public PortalApplicationView getPortalApplicationView(
307: HttpServletRequest request, ClientInfo clInfo)
308: throws ServletException {
309: Vector<PortalPage> v = new Vector<PortalPage>(
310: this .paPages.length);
311: for (int i = 0; i < this .paPages.length; i++) {
312: if (this .paPages[i].getViewPermission() == null) {
313: v.add(paPages[i]);
314: } else {
315: if (paPages[i].getViewPermission().isSatisfied(request,
316: paPages[i]))
317: v.add(paPages[i]);
318: }
319: }
320: PortalPage[] viewablePages = new PortalPage[v.size()];
321: v.copyInto(viewablePages);
322: return new PortalApplicationView(viewablePages, this , clInfo,
323: request);
324: }
325:
326: protected synchronized int getNextID() {
327: return ++paIdCounter;
328: }
329:
330: protected synchronized int getNextPageID() {
331: return ++paPageIdCounter;
332: }
333:
334: @XmlTransient
335: public String getIdPrefix() {
336: return this .paIdPrefix;
337: }
338:
339: public void setDisplayInfo(DisplayInfo dInfo) {
340: this .paDisplayInfo = dInfo;
341: }
342:
343: @XmlTransient
344: public DisplayInfo getDisplayInfo() {
345: return this .paDisplayInfo;
346: }
347:
348: public void afterUnmarshal(Unmarshaller um, Object parent) {
349: super .afterUnmarshal(um, parent);
350:
351: try {
352: int maxPageIndex = 0;
353: for (int i = 0; i < this .paPages.length; i++) {
354: PortalPage p = this .paPages[i];
355: p.setPortalApplication(this );
356: if (p.getIndex() > maxPageIndex)
357: maxPageIndex = p.getIndex();
358: int maxId = p.getMaxId();
359: if (maxId > this .paIdCounter)
360: this .paIdCounter = maxId;
361: }
362: this .paPageIdCounter = maxPageIndex;
363: if (paOwnerName != null) {
364: paOwnerId = UserAdminServiceLocator
365: .getUserAdminService().getUser(paOwnerName)
366: .getId();
367: }
368: computeLogoImage();
369: } catch (Exception e) {
370: this .paLogger.error(
371: "Failed to unmarshal portal application.", e);
372: }
373:
374: }
375:
376: /**
377: * Add a new tab to the display at the given index. If the index
378: * is negative or out of range, it adds it at the end.
379: */
380: public void addPage(PortalPage newPage, int index) {
381:
382: newPage.setPortalApplication(this );
383: if (index < 0 || index >= paPages.length) {
384: // Add at the end
385: index = paPages.length;
386: }
387:
388: PortalPage[] newPages = new PortalPage[paPages.length + 1];
389:
390: for (int i = 0; i < index; i++) {
391: newPages[i] = paPages[i];
392: }
393:
394: newPages[index] = newPage;
395: int newLen = newPages.length;
396:
397: for (int i = index + 1; i < newLen; i++) {
398: newPages[i] = paPages[i - 1];
399: }
400:
401: paPages = newPages;
402:
403: }
404:
405: /**
406: * Delete an existing page if the index is within the range.
407: */
408: public void deletePage(int index) {
409:
410: if (index < 0 || index >= paPages.length) {
411: return;
412: }
413:
414: PortalPage[] newPages = new PortalPage[paPages.length - 1];
415:
416: for (int i = 0; i < index; i++) {
417: newPages[i] = paPages[i];
418: }
419:
420: int newLen = newPages.length;
421:
422: for (int i = index; i < newLen; i++) {
423: newPages[i] = paPages[i + 1];
424: }
425:
426: paPages = newPages;
427:
428: }
429:
430: public void deletePage(PortalPage p) {
431: for (int i = 0; i < this .paPages.length; i++) {
432: if (this .paPages[i].equals(p)) {
433: deletePage(i);
434: return;
435: }
436: }
437: }
438:
439: /**
440: * Re-ordering tab
441: * @param oldIndex
442: * @param newIndex
443: */
444: public void reorderPage(int oldIndex, int newIndex) {
445: if (oldIndex < 0 || oldIndex >= paPages.length)
446: return;
447: if (newIndex < 0 || newIndex >= paPages.length)
448: return;
449: if (oldIndex == newIndex)
450: return;
451:
452: if (oldIndex < newIndex) {
453: PortalPage oldTab = paPages[oldIndex];
454: for (int i = oldIndex; i < newIndex; i++) {
455: paPages[i] = paPages[i + 1];
456: }
457: paPages[newIndex] = oldTab;
458: } else {
459: PortalPage oldTab = paPages[oldIndex];
460: for (int i = oldIndex; i > newIndex; i--) {
461: paPages[i] = paPages[i - 1];
462: }
463: paPages[newIndex] = oldTab;
464:
465: }
466: }
467:
468: public void reorderPage(PortalPage p, int oldIndex, int newIndex) {
469: if (this .paPages[oldIndex].equals(p)) {
470: reorderPage(oldIndex, newIndex);
471: } else {
472: // Need to figure out the real index
473: int realOldIndex = -1;
474: for (int i = 0; i < this .paPages.length; i++) {
475: if (this .paPages[i].equals(p)) {
476: realOldIndex = i;
477: break;
478: }
479: }
480: int realNewIndex = realOldIndex + newIndex - oldIndex;
481: if (realNewIndex < 0)
482: realNewIndex = 0;
483: if (realNewIndex >= this .paPages.length)
484: realNewIndex = this .paPages.length - 1;
485: reorderPage(realOldIndex, realNewIndex);
486: }
487: }
488:
489: public PortalPage createPage(String pageName, String template,
490: int refreshSeconds) throws InstantiationException,
491: IllegalAccessException, ClassNotFoundException {
492: PortalPage p = new PortalPage();
493: p.setName(pageName);
494: p.setPortalApplication(this );
495: CompositeRenderable r = PortalConfiguration.getInstance()
496: .getRenderableForTemplate(template);
497: r.setTemplate(template);
498: r.setRefreshSeconds(refreshSeconds);
499: p.setRenderable(r);
500: r.setPortalPage(p);
501: addPage(p, -1);
502: return p;
503: }
504:
505: public static void main(String[] args) {
506:
507: try {
508:
509: JAXBContext jc = JAXBContext
510: .newInstance("com.nabhinc.condition:com.nabhinc.portal.model");
511:
512: Unmarshaller u = jc.createUnmarshaller();
513: PortalApplication pc = (PortalApplication) u
514: .unmarshal(new FileInputStream(
515: "C:\\AllData\\eclipse\\workspace\\Stringbeans40\\WebContent\\WEB-INF\\portal_apps\\home.xml"));
516:
517: Marshaller m = jc.createMarshaller();
518: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
519: ByteArrayOutputStream sos = new ByteArrayOutputStream();
520: m.marshal(pc, sos);
521: String xml = sos.toString();
522: System.out.println(xml);
523:
524: u.unmarshal(new StringReader(xml));
525: } catch (Exception e) {
526: e.printStackTrace();
527: }
528:
529: }
530:
531: public boolean isMemberOf(String userName) {
532: try {
533: return PortalInformationStoreLocator
534: .getPortalInformationStore().isMemberOf(userName,
535: this .paPath);
536: } catch (RemoteException e) {
537: this .paLogger.error("Failed to check psite membership.", e);
538: return false;
539: }
540: }
541:
542: }
|