From 18196e775a3bbcb9f25548a3fcb36036ac30774c Mon Sep 17 00:00:00 2001 From: pb Date: Wed, 13 Feb 2013 18:08:44 +0000 Subject: [PATCH] =?UTF-8?q?Portlet=20LBookmarksaus=20contrib=20WestSussex?= =?UTF-8?q?=20hinzugef=C3=BCgt.=20Muss=20noch=20weiter=20angepasst=20werde?= =?UTF-8?q?n.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.libreccm.org/ccm/trunk@2071 8810af33-2d31-482b-a856-94f89814c4df --- ccm-portlet-bookmarks/application.xml | 30 ++ .../arsdigita/portlet/BookmarksPortlet.pdl | 81 ++++ .../oracle-se-create.sql | 2 + .../ccm-portlet-bookmarks/postgres-create.sql | 4 + .../upgrade/oracle-se-1.0.1-1.0.2.sql | 14 + .../src/ccm-portlet-bookmarks.config | 5 + .../src/ccm-portlet-bookmarks.load | 15 + .../arsdigita/portlet/bookmarks/Bookmark.java | 155 ++++++++ .../portlet/bookmarks/BookmarkConstants.java | 63 +++ .../portlet/bookmarks/BookmarksPortlet.java | 224 +++++++++++ .../bookmarks/BookmarksPortletConfig.java | 49 +++ ...ookmarksPortletConfig_parameter.properties | 4 + .../portlet/bookmarks/Initializer.java | 123 ++++++ .../arsdigita/portlet/bookmarks/Loader.java | 62 +++ .../bookmarks/Loader_parameter.properties | 5 + .../bookmarks/ui/BookmarkResources.properties | 12 + .../bookmarks/ui/BookmarkSelectionModel.java | 67 ++++ .../bookmarks/ui/BookmarksPortletAdder.java | 73 ++++ .../bookmarks/ui/BookmarksPortletEditor.java | 374 ++++++++++++++++++ .../ui/BookmarksPortletRenderer.java | 123 ++++++ .../portlet/bookmarks/ui/BookmarksTable.java | 257 ++++++++++++ .../ui/BookmarksTableModelBuilder.java | 65 +++ .../heirloom/images/portlets/arrow_bullet.gif | Bin 0 -> 67 bytes .../heirloom/portlets/bookmarks-portlet.xsl | 40 ++ 24 files changed, 1847 insertions(+) create mode 100644 ccm-portlet-bookmarks/application.xml create mode 100644 ccm-portlet-bookmarks/pdl/com/arsdigita/portlet/BookmarksPortlet.pdl create mode 100644 ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/oracle-se-create.sql create mode 100644 ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/postgres-create.sql create mode 100644 ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/upgrade/oracle-se-1.0.1-1.0.2.sql create mode 100644 ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.config create mode 100644 ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.load create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Bookmark.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarkConstants.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortlet.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig_parameter.properties create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Initializer.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader_parameter.properties create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkResources.properties create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkSelectionModel.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletAdder.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletEditor.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletRenderer.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTable.java create mode 100644 ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTableModelBuilder.java create mode 100644 ccm-portlet-bookmarks/web/themes/heirloom/images/portlets/arrow_bullet.gif create mode 100644 ccm-portlet-bookmarks/web/themes/heirloom/portlets/bookmarks-portlet.xsl diff --git a/ccm-portlet-bookmarks/application.xml b/ccm-portlet-bookmarks/application.xml new file mode 100644 index 000000000..f976dfe7a --- /dev/null +++ b/ccm-portlet-bookmarks/application.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + Portlet that allows users to store internal and external links. + + Ported from West Sussex contribution: ccm-wsx-bookmarks-portlet, created by + Chris Gilbert. + + diff --git a/ccm-portlet-bookmarks/pdl/com/arsdigita/portlet/BookmarksPortlet.pdl b/ccm-portlet-bookmarks/pdl/com/arsdigita/portlet/BookmarksPortlet.pdl new file mode 100644 index 000000000..157de5c6e --- /dev/null +++ b/ccm-portlet-bookmarks/pdl/com/arsdigita/portlet/BookmarksPortlet.pdl @@ -0,0 +1,81 @@ +// author chris gilbert +// model for a portlet that holds a list of bookmark links + +model uk.gov.westsussex.portlet; + +import com.arsdigita.portal.Portlet; +import com.arsdigita.cms.contenttypes.Link; + +object type BookmarksPortlet extends Portlet { + +} + + +object type Bookmark extends Link { + +} + + +association { + + + component Bookmark[0..n] bookmarks = join portlets.portlet_id to portlet_bookmarks.portlet_id, + join portlet_bookmarks.target_id to cms_links.link_id; + BookmarksPortlet[0..1] portlet = join cms_links.link_id to portlet_bookmarks.target_id, + join portlet_bookmarks.portlet_id to portlets.portlet_id; + + + +} + +data operation swapRelatedLinkWithNextInGroup { + do { + update cms_links + set link_order = CASE WHEN (link_order = :linkOrder) THEN + (:nextLinkOrder) + ELSE + (:linkOrder) + END + where (link_order = :linkOrder or link_order = :nextLinkOrder) + and (select portlet_id from portlet_bookmarks where target_id=link_id) = :ownerID + and 2 = (select count(*) from cms_links l, portlet_bookmarks b + where l.link_id=b.target_id + and (link_order = :linkOrder or link_order = :nextLinkOrder) + and portlet_id = :ownerID) + } +} + +query minRelatedLinkOrderForPortlet { + Integer linkOrder; + + options { + WRAP_QUERIES = false; + } + + do { + select min(link_order) as link_order from cms_links l, portlet_bookmarks b + where b.portlet_id = :ownerID and l.link_id = b.target_id + } map { + linkOrder = link_order; + } +} + +query maxRelatedLinkOrderForPortlet { + Integer linkOrder; + + options { + WRAP_QUERIES = false; + } + + do { + select max(link_order) as link_order from cms_links l, portlet_bookmarks b + where b.portlet_id = :ownerID and l.link_id = b.target_id + } map { + linkOrder = link_order; + } +} + + + + + diff --git a/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/oracle-se-create.sql b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/oracle-se-create.sql new file mode 100644 index 000000000..1c59f651a --- /dev/null +++ b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/oracle-se-create.sql @@ -0,0 +1,2 @@ +@ ddl/oracle-se/create.sql +@ ddl/oracle-se/deferred.sql diff --git a/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/postgres-create.sql b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/postgres-create.sql new file mode 100644 index 000000000..2a326455c --- /dev/null +++ b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/postgres-create.sql @@ -0,0 +1,4 @@ +begin; +\i ddl/postgres/create.sql +\i ddl/postgres/deferred.sql +end; diff --git a/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/upgrade/oracle-se-1.0.1-1.0.2.sql b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/upgrade/oracle-se-1.0.1-1.0.2.sql new file mode 100644 index 000000000..307361992 --- /dev/null +++ b/ccm-portlet-bookmarks/sql/ccm-portlet-bookmarks/upgrade/oracle-se-1.0.1-1.0.2.sql @@ -0,0 +1,14 @@ +update cms_links x +set link_order = nvl((select sort_key + from portlet_bookmarks y + where y.target_id = x.link_id), x.link_order); +commit; + +alter table portlet_bookmarks +drop column sort_key; + +update acs_objects +set object_type = 'uk.gov.westsussex.portlet.Bookmark', + default_domain_class = 'uk.gov.westsussex.portlet.bookmarks.Bookmark' +where object_id in (select target_id + from portlet_bookmarks); \ No newline at end of file diff --git a/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.config b/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.config new file mode 100644 index 000000000..ee8a150bc --- /dev/null +++ b/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.config @@ -0,0 +1,5 @@ + + + + diff --git a/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.load b/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.load new file mode 100644 index 000000000..6e53425e9 --- /dev/null +++ b/ccm-portlet-bookmarks/src/ccm-portlet-bookmarks.load @@ -0,0 +1,15 @@ + + + +
+ + + +
+ + + + + + + diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Bookmark.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Bookmark.java new file mode 100644 index 000000000..7d18bd0bb --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Bookmark.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks; + +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + +import com.arsdigita.cms.contenttypes.Link; +import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.persistence.DataCollection; +import com.arsdigita.persistence.DataObject; +import com.arsdigita.persistence.DataOperation; +import com.arsdigita.persistence.DataQuery; +import com.arsdigita.persistence.OID; +import com.arsdigita.persistence.Session; +import com.arsdigita.persistence.SessionManager; + +/** + * + * Extends link, but has no additional data. Extension is to enable overriding + * of swap methods which don't work in Link - if you delete a link in the middle + * you cannot move links past the resulting gap + * + * @author Chris Gilbert (cgyg9330) + */ +public class Bookmark extends Link implements BookmarkConstants{ + + /** Private Logger instance for debugging purpose. */ + private static Logger s_log = Logger.getLogger(Bookmark.class); + + /** PDL stuff */ + public static String BASE_DATA_OBJECT_TYPE = + "com.arsdigita.portlet.Bookmark"; + + public Bookmark() { + super(BASE_DATA_OBJECT_TYPE); + } + + public Bookmark(DataObject data) { + super(data); + } + + public Bookmark( OID id ) throws DataObjectNotFoundException { + super( id ); + } + + public Bookmark( BigDecimal id ) throws DataObjectNotFoundException { + this( new OID( BASE_DATA_OBJECT_TYPE, id ) ); + } + + /** + * Swaps this Bookmark with the next one, + * according to the linkOrder + */ + @Override + public void swapWithNext() { + s_log.debug("Start - swapWithNext"); + swapWithNext("com.arsdigita.portlet.minRelatedLinkOrderForPortlet", + "com.arsdigita.portlet.swapRelatedLinkWithNextInGroup"); + } + + /** + * Swaps this Bookmark with the previous one, + * according to the linkOrder + */ + @Override + public void swapWithPrevious() { + s_log.debug("Start - swapWithPrevious"); + swapWithPrevious("com.arsdigita.portlet.maxRelatedLinkOrderForPortlet", + "com.arsdigita.portlet.swapRelatedLinkWithNextInGroup"); + } + + /** + * Given a dataquery name, returns the (possibly filtered) + * DataQuery for use in swapKeys. This implementation filters + * on the portlet property, so that only + * Bookmarks which belong to the same BookmarksPortlet + * will be swapped. + * + * @param queryName name of the DataQuery to use + * @return the DataQuery + */ + @Override + protected DataQuery getSwapQuery(String queryName) { + DataQuery query = super.getSwapQuery(queryName); + BigDecimal portletID = BookmarksPortlet + .getPortletForBookmark(this).getID(); + s_log.debug("setting owner in swapquerie as " + portletID); + query.setParameter("ownerID", portletID); + return query; + } + + /** + * Given a data operation name, returns the + * DataOperation for use in swapKeys. This implementation sets the + * portlet parameter, in addition to what is set by + * super.getSwapOperation + * + * @param operationName the Name of the DataOperation to use + * + * @return the DataOperation used to swap the sort keys. + */ + @Override + protected DataOperation getSwapOperation(String operationName) { + DataOperation operation = super.getSwapOperation(operationName); + BigDecimal portletID = + BookmarksPortlet.getPortletForBookmark(this).getID(); + s_log.debug("setting owner in swapoperation as " + portletID); + + operation.setParameter("ownerID", portletID); + return operation; + } + + /** + * This method is only used for setting initial sort keys for + * links which exist without them. This is called by swapKeys + * instead of attempting to swap if the key found is + * null. This implementation sorts all Bookmarks owned by this + * Bookmark's portlet by title. + */ + @Override + protected void alphabetize() { + Session session = SessionManager.getSession(); + DataCollection links = session.retrieve(BASE_DATA_OBJECT_TYPE); + links.addEqualsFilter( PORTLET + ".id", + BookmarksPortlet.getPortletForBookmark(this).getID()); + links.addOrder(TITLE); + int sortKey = 0; + while (links.next()) { + sortKey++; + Link link = new Bookmark(links.getDataObject()); + link.setOrder(sortKey); + link.save(); + } + + } + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarkConstants.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarkConstants.java new file mode 100644 index 000000000..328ee84b8 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarkConstants.java @@ -0,0 +1,63 @@ +/* + * Created on 10-Sep-04 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package com.arsdigita.portlet.bookmarks; + +import com.arsdigita.bebop.Label; +import com.arsdigita.globalization.GlobalizedMessage; + +/** + * @author cgyg9330 + * + * Constants used by classes in the bookmarksportlet application. + * + */ + +public interface BookmarkConstants { + + public static final String BUNDLE_NAME = "uk.gov.westsussex.portlet.bookmarks.ui.BookmarkResources"; + + + // bookmark portlet attributes + public static final String BOOKMARKS = "bookmarks"; + public static final String PORTLET = "portlet"; + public static final String SORT_KEY = "sortKey"; + + // bookmark attribute values (nb target types defined in com.arsdigita.cms.contenttypes.Link used + + public static final String NEW_WINDOW_YES = "_blank"; + public static final String NEW_WINDOW_NO = null; + + + // rendering + + public static final String XML_BOOKMARK_NS = "http://wsgfl.westsussex.gov.uk/portlet/bookmarks/1.0"; + public static final String MAIN_BOOKMARK_PORTLET_ELEMENT = "portlet:bookmarks"; + public static final String BOOKMARK_ELEMENT = "bookmark-portlet:bookmark"; + public static final String TITLE_ATTRIBUTE = "title"; + public static final String URL_ATTRIBUTE = "url"; + public static final String WINDOW_ATTRIBUTE = "target-window"; + + + // editing + + public static final String NO_BOOKMARKS_YET = (String)new GlobalizedMessage("bookmarks.header.no-bookmarks", BUNDLE_NAME).localize(); + public static final String EXISTING_BOOKMARKS = (String)new GlobalizedMessage("bookmarks.header.existing-bookmarks", BUNDLE_NAME).localize(); + public static final String NEW_WINDOW = (String)new GlobalizedMessage("bookmarks.new-window", BUNDLE_NAME).localize(); + public static final Label ADD_NEW_BOOKMARK_LABEL = new Label((String)new GlobalizedMessage("bookmarks.add", BUNDLE_NAME).localize(), Label.BOLD); + public static final Label TITLE_LABEL = new Label((String)new GlobalizedMessage("bookmarks.title", BUNDLE_NAME).localize(), Label.BOLD); + public static final Label DESCRIPTION_LABEL = new Label((String)new GlobalizedMessage("bookmarks.description", BUNDLE_NAME).localize(), Label.BOLD); + public static final Label URL_LABEL = new Label((String)new GlobalizedMessage("bookmarks.url", BUNDLE_NAME).localize(), Label.BOLD); + + // errors + + public static final String NO_URL = (String)new GlobalizedMessage("bookmarks.error.no-url", BUNDLE_NAME).localize(); + public static final String NO_TITLE = (String)new GlobalizedMessage("bookmarks.error.no-title", BUNDLE_NAME).localize(); + public static final String CONTENT_ITEM_NOT_FOUND = (String)new GlobalizedMessage("bookmarks.error.content-item-not-found", BUNDLE_NAME).localize(); + public static final String CONTENT_ITEM_NOT_AVAILABLE = (String)new GlobalizedMessage("bookmarks.warning.item-not-available", BUNDLE_NAME).localize(); + + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortlet.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortlet.java new file mode 100644 index 000000000..162632d02 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortlet.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks; + + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.portal.AbstractPortletRenderer; +import com.arsdigita.cms.ContentItem; +import com.arsdigita.cms.SecurityManager; +import com.arsdigita.cms.contenttypes.Link; +import com.arsdigita.cms.dispatcher.ItemResolver; +import com.arsdigita.cms.dispatcher.MultilingualItemResolver; +import com.arsdigita.kernel.Kernel; +import com.arsdigita.kernel.Party; +import com.arsdigita.kernel.permissions.PermissionService; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +import com.arsdigita.persistence.DataAssociation; +import com.arsdigita.persistence.DataAssociationCursor; +import com.arsdigita.persistence.DataCollection; +import com.arsdigita.persistence.DataObject; +import com.arsdigita.persistence.Filter; +import com.arsdigita.persistence.FilterFactory; +import com.arsdigita.persistence.SessionManager; +import com.arsdigita.portal.Portlet; +import com.arsdigita.portlet.bookmarks.ui.BookmarksPortletRenderer; +import com.arsdigita.web.URL; + +import org.apache.log4j.Logger; + + +/** + * Displays a collection of links, that may be internal or external. + * + * @author cgyg9330 + */ +public class BookmarksPortlet extends Portlet implements BookmarkConstants { + + /** Private Logger instance for debugging purpose. */ + public static final Logger s_log = Logger.getLogger(BookmarksPortlet.class); + + public static final String BASE_DATA_OBJECT_TYPE = + "uk.gov.westsussex.portlet.BookmarksPortlet"; + + private static BookmarksPortletConfig s_config = + new BookmarksPortletConfig(); + + static { + s_config.load(); + } + + public static BookmarksPortletConfig getConfig() { + return s_config; + } + + public BookmarksPortlet(DataObject dataObject) { + super(dataObject); + } + + @Override + protected String getBaseDataObjectType() { + return BASE_DATA_OBJECT_TYPE; + } + + @Override + protected AbstractPortletRenderer doGetPortletRenderer() { + return new BookmarksPortletRenderer(this); + + } + /** + * associate a Bookmark with this portlet and place it after existing + * Bookmarks + * + * @param bookmark + */ + public void addBookmark(Bookmark bookmark) { + DataAssociationCursor bookmarks = + ((DataAssociation) get(BOOKMARKS)).cursor(); + bookmarks.addOrder(Link.ORDER + " desc"); + int key = 1; + if (bookmarks.next()) { + key = ((Integer) bookmarks.get(Link.ORDER)).intValue() + 1; + + } + bookmarks.close(); + bookmark.setOrder(key); + add(BOOKMARKS, bookmark); + + } + + /** + * Return a url for an internal or external link - used for displaying + * the link in edit view (we don't want to just display an item id + * when the link is internal as that doesn't mean anything to non authors) + * + * @param link + * @param state + * @return + */ + public static String getURIForBookmark(Bookmark bookmark, PageState state) { + + String url = null; + + if (bookmark.getTargetType().equals(Link.EXTERNAL_LINK)) { + url = bookmark.getTargetURI(); + } else { + + ItemResolver resolver = new MultilingualItemResolver(); + ContentItem item = bookmark.getTargetItem(); + if (item != null) { + item = item.getLiveVersion(); + if (item != null) { + + url = + resolver.generateItemURL( + state, + item, + item.getContentSection(), + ContentItem.LIVE); + url = URL.there(state.getRequest(), url).toString(); + } + + } + + } + return url; + } + + /** + * Retrieve the bookmarks for this portlet in their correct order + * @return + */ + public DataCollection getBookmarks() { + + DataAssociationCursor cursor = + ((DataAssociation) get(BOOKMARKS)).cursor(); + cursor.addOrder(Link.ORDER); + if (getConfig().checkPermissions()) { + + Party party = Kernel.getContext().getParty(); + if (party == null) { + party = Kernel.getPublicUser(); + } + + FilterFactory factory = cursor.getFilterFactory(); + /* cursor.addFilter(PermissionService.getFilterQuery(factory, "targetItem", + PrivilegeDescriptor.get(SecurityManager.CMS_READ_ITEM), + party.getOID()));*/ + + // need to or it here so that we don't exclude external links + Filter filter = + factory.or().addFilter( + factory.equals("targetItem", null)).addFilter( + PermissionService.getFilterQuery( + factory, + "targetItem", + PrivilegeDescriptor.get(SecurityManager.CMS_READ_ITEM), + party.getOID())); + // this extra and 1=1 is a fiddle to ensure the query is bracketed properly. + // I needed it to be + // 'get links for this portlet and ((link is not a content item) or (user has access to item))' + // but just adding the or filter produced + // 'get links for this portlet and (link is not a content item) or (user has access to item)' + // with the result that all content item links were returned regardless of which portlet they belonged to + cursor.addFilter(factory.and().addFilter(filter).addFilter("1=1")); + + } + + return cursor; + } + + /** + * + * Return the owner of the given bookmark + * + * @param bookmark + * @return + */ + public static BookmarksPortlet getPortletForBookmark(Bookmark bookmark) { + // what the hell's this????? bookmark <-> portlet is a two way association + // so we should be using the association programatically to get the portlet + // Never mind, I'm sure it boils down to the same sql anyway + DataCollection portlets = + SessionManager.getSession().retrieve( + BookmarksPortlet.BASE_DATA_OBJECT_TYPE); + portlets.addEqualsFilter(BOOKMARKS, bookmark.getID()); + BookmarksPortlet portlet = null; + while (portlets.next()) { + portlet = new BookmarksPortlet(portlets.getDataObject()); + } + return portlet; + + } + + public void renumberBookmarks() { + DataCollection bookmarks = getBookmarks(); + bookmarks.addOrder(Link.ORDER); + int sortKey = 0; + while (bookmarks.next()) { + sortKey++; + Bookmark link = new Bookmark(bookmarks.getDataObject()); + link.setOrder(sortKey); + + } + + } +} + + diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig.java new file mode 100644 index 000000000..9e9f19b25 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package com.arsdigita.portlet.bookmarks; + +import com.arsdigita.runtime.AbstractConfig; +import com.arsdigita.util.parameter.BooleanParameter; +import com.arsdigita.util.parameter.Parameter; + +/** + * Configuration allows links to be access controlled (so homepage admin + * can add links that only selected users can see). + * + * @author Chris Gilbert (cgyg9330) <chris.gilbert@westsussex.gov.uk> + * @version $Id: BookmarksPortletConfig.java 2007/08/08 09:28:26 cgyg9330 $ + */ +public class BookmarksPortletConfig extends AbstractConfig { + + private BooleanParameter checkPermissions = new BooleanParameter( + "uk.gov.westsussex.portlet.bookmarks.checkPermissions", + Parameter.REQUIRED, new Boolean(false)); + + public BookmarksPortletConfig() { + + register(checkPermissions); + loadInfo(); + } + + public boolean checkPermissions() { + return ((Boolean) get(checkPermissions)).booleanValue(); + } + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig_parameter.properties b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig_parameter.properties new file mode 100644 index 000000000..560aa6744 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/BookmarksPortletConfig_parameter.properties @@ -0,0 +1,4 @@ +uk.gov.westsussex.portlet.bookmarks.checkPermissions.title=Check for access to bookmarks +uk.gov.westsussex.portlet.bookmarks.checkPermissions.purpose=allow home page admin to create links which only certain users can see +uk.gov.westsussex.portlet.bookmarks.checkPermissions.example=false +uk.gov.westsussex.portlet.bookmarks.checkPermissions.format=[boolean] diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Initializer.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Initializer.java new file mode 100644 index 000000000..4e64f405b --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Initializer.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package com.arsdigita.portlet.bookmarks; + + +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.db.DbHelper; +import com.arsdigita.domain.DomainObject; +import com.arsdigita.kernel.ACSObjectInstantiator; +import com.arsdigita.kernel.ResourceType; +import com.arsdigita.kernel.ResourceTypeConfig; +import com.arsdigita.kernel.ui.ResourceConfigFormSection; +import com.arsdigita.persistence.DataObject; +import com.arsdigita.persistence.pdl.ManifestSource; +import com.arsdigita.persistence.pdl.NameFilter; +import com.arsdigita.portal.PortletType; +import com.arsdigita.portlet.bookmarks.ui.BookmarksPortletAdder; +import com.arsdigita.portlet.bookmarks.ui.BookmarksPortletEditor; +import com.arsdigita.runtime.CompoundInitializer; +import com.arsdigita.runtime.DomainInitEvent; +import com.arsdigita.runtime.PDLInitializer; +import com.arsdigita.runtime.RuntimeConfig; + +/** + * based on com.arsdigita.london.portal.installer.portlet + * + * @author cgyg9330 (Chris Gilbert) + * @version $Id: Initializer.java,v 1.3 2005/06/08 14:45:43 cgyg9330 Exp $ + */ +public class Initializer extends CompoundInitializer { + + + /** + * Constructor. + */ + public Initializer() { + final String url = RuntimeConfig.getConfig().getJDBCURL(); + final int database = DbHelper.getDatabaseFromURL(url); + + add( + new PDLInitializer( + new ManifestSource( + "ccm-wsx-bookmarks-portlet.pdl.mf", + new NameFilter( + DbHelper.getDatabaseSuffix(database), + "pdl")))); + } + + /** + * + * @param e + */ + @Override + public void init(DomainInitEvent e) { + super.init(e); + + e.getFactory().registerInstantiator( + BookmarksPortlet.BASE_DATA_OBJECT_TYPE, + new ACSObjectInstantiator() { + @Override + public DomainObject doNewInstance(DataObject dataObject) { + return new BookmarksPortlet(dataObject); + } + }); + + e.getFactory().registerInstantiator( + Bookmark.BASE_DATA_OBJECT_TYPE, + new ACSObjectInstantiator() { + @Override + public DomainObject doNewInstance(DataObject dataObject) { + return new Bookmark(dataObject); + } + }); + + new ResourceTypeConfig(BookmarksPortlet.BASE_DATA_OBJECT_TYPE) { + @Override + public ResourceConfigFormSection getCreateFormSection( + final ResourceType resType, + final RequestLocal parentAppRL) { + + final ResourceConfigFormSection config = + new BookmarksPortletAdder(resType, parentAppRL); + + return config; + } + + @Override + public ResourceConfigFormSection getModifyFormSection( + final RequestLocal application) { + + final BookmarksPortletEditor config = + new BookmarksPortletEditor(application); + return config; + } + }; + + + /** + * implementation of framework that allows portlets to be bundled up + * as discrete applications + */ + PortletType.registerXSLFile(BookmarksPortlet.BASE_DATA_OBJECT_TYPE, + "/packages/westsussex-portlets/xsl/bookmarks-portlet.xsl"); + + } +} \ No newline at end of file diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader.java new file mode 100644 index 000000000..02f3dbe5c --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks; + +import com.arsdigita.kernel.Kernel; +import com.arsdigita.kernel.KernelExcursion; +import com.arsdigita.loader.PackageLoader; +import com.arsdigita.portal.PortletType; +import com.arsdigita.runtime.ScriptContext; +import com.arsdigita.util.parameter.Parameter; +import com.arsdigita.util.parameter.StringParameter; + + +/** + * Just create the portlet type - includes Load parameter (that can be + * set via interactive load) for the type name, though this can be + * changed in the DB later if required in application_types table + * + * @author cgyg9330 + * @version $Id: Loader.java,v 1.1 2005/02/25 08:41:56 cgyg9330 Exp $ + */ +public class Loader extends PackageLoader { + + private StringParameter typeName = new StringParameter + ("uk.gov.westsussex.portlet.bookmarks.name", + Parameter.REQUIRED, "My Links"); + + public Loader() { + register(typeName); + + } + public void run(final ScriptContext ctx) { + new KernelExcursion() { + public void excurse() { + setEffectiveParty(Kernel.getSystemParty()); + PortletType type = PortletType + .createPortletType((String)get(typeName), + PortletType.WIDE_PROFILE, + BookmarksPortlet.BASE_DATA_OBJECT_TYPE); + type.setDescription("Allows users to maintain a list of internal and external links"); + } + }.run(); + } + + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader_parameter.properties b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader_parameter.properties new file mode 100644 index 000000000..d59cf088d --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/Loader_parameter.properties @@ -0,0 +1,5 @@ +uk.gov.westsussex.portlet.bookmarks.name.title=Portlet Type Name +uk.gov.westsussex.portlet.bookmarks.name.purpose=The name of the portlet type that appears in the drop down list of portlet types +uk.gov.westsussex.portlet.bookmarks.name.example=Bookmarks +uk.gov.westsussex.portlet.bookmarks.name.format=[string] + diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkResources.properties b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkResources.properties new file mode 100644 index 000000000..3f16d5a19 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkResources.properties @@ -0,0 +1,12 @@ +bookmarks.header.no-bookmarks=No links defined yet +bookmarks.header.existing-bookmarks=Existing links (check to delete) +bookmarks.new-window=open in a new window +bookmarks.add=Specify the full address (starting http://) - you can cut and paste addresses from this site: +bookmarks.description=Description: +bookmarks.title=Title: +bookmarks.url=URL: +bookmarks.error.no-url=Please enter a url +bookmarks.error.no-title=Please enter a title for the link +bookmarks.error.content-item-not-found=Page could not be found on this site +bookmarks.warning.item-not-available=Page not currently available on this site + diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkSelectionModel.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkSelectionModel.java new file mode 100644 index 000000000..fe6d4554f --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarkSelectionModel.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks.ui; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.kernel.ui.ACSObjectSelectionModel; +import com.arsdigita.portlet.bookmarks.Bookmark; + + +/** + * SelectionModel to track the current Bookmark object for view/edit + * purposes. - copied from authoring ui + * Bit pointless really - it just saves a bit of casting. Just as easy + * to use ACSObjectSelectionModel direct + */ +public class BookmarkSelectionModel extends ACSObjectSelectionModel { + + public BookmarkSelectionModel(BigDecimalParameter param) { + super(Bookmark.class.getName(), + Bookmark.BASE_DATA_OBJECT_TYPE, + param); + } + + /** + * Construct a new BookmarkSelectionModel + * + * @param itemClass The name of the Java class which represents + * the content item. Must be a subclass of Link. In + * addition, the class must have a constructor with a single + * OID parameter. + * @param objectType The name of the persistence metadata object type + * which represents the content item. In practice, will often be + * the same as the itemClass. + * @param parameter The state parameter which should be used by this item + */ + public BookmarkSelectionModel(String itemClass, String objectType, + BigDecimalParameter parameter) { + super(itemClass, objectType, parameter); + } + + /** + * Returns the currently-selected Bookmark + * + * @param state the PageState for the current request. + * @return The current Bookmark + */ + public Bookmark getSelectedLink(PageState state) { + return (Bookmark)getSelectedObject(state); + } +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletAdder.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletAdder.java new file mode 100644 index 000000000..d6ab72d27 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletAdder.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks.ui; + +import com.arsdigita.portlet.bookmarks.BookmarkConstants; + +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.HorizontalLine; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.bebop.portal.PortletConfigFormSection; +import com.arsdigita.kernel.ResourceType; + +/** + * Adder creates a new bookmarks portlet without any bookmarks. + * + * Note this is the only portlet I have seen where a different form is + * registered for adding and editing. + * + * It is necessary here because we need to create a persistent portlet instance + * before we can associate links with it. + * + * @author cgyg9330 + */ +public class BookmarksPortletAdder + extends PortletConfigFormSection + implements BookmarkConstants { + + + public BookmarksPortletAdder( + ResourceType resType, + RequestLocal parentAppRL) { + super(resType, parentAppRL); + } + + + protected void addWidgets() { + + /*add( + new Label( + "Create links to your favourite websites or pages on this site. Specify the full address (starting http://) - you can cut and paste addresses from this site.", + Label.BOLD), + ColumnPanel.FULL_WIDTH);*/ + super.addWidgets(); + add(new HorizontalLine(), ColumnPanel.FULL_WIDTH); + + add( + new Label( + "Give the portlet a title and save it now, then edit it to add bookmarks.", + Label.BOLD), + ColumnPanel.FULL_WIDTH); + add(new HorizontalLine(), ColumnPanel.FULL_WIDTH); + + + } + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletEditor.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletEditor.java new file mode 100644 index 000000000..f75f2c438 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletEditor.java @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.portlet.bookmarks.ui; + +import java.net.MalformedURLException; +import java.util.StringTokenizer; +import java.util.TooManyListenersException; + + +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.HorizontalLine; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.bebop.event.PrintEvent; +import com.arsdigita.bebop.event.PrintListener; +import com.arsdigita.bebop.form.CheckboxGroup; +import com.arsdigita.bebop.form.Option; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.bebop.portal.PortletConfigFormSection; +import com.arsdigita.bebop.portal.PortletSelectionModel; +import com.arsdigita.cms.ContentItem; +import com.arsdigita.cms.ContentSection; +import com.arsdigita.cms.ContentSectionCollection; +import com.arsdigita.cms.SecurityManager; +import com.arsdigita.cms.contenttypes.Link; +import com.arsdigita.cms.dispatcher.CMSDispatcher; +import com.arsdigita.cms.dispatcher.ItemResolver; +import com.arsdigita.portal.Portlet; +import com.arsdigita.portlet.bookmarks.Bookmark; +import com.arsdigita.portlet.bookmarks.BookmarkConstants; +import com.arsdigita.portlet.bookmarks.BookmarksPortlet; +import com.arsdigita.util.UncheckedWrapperException; +import com.arsdigita.web.Application; +import com.arsdigita.web.URL; +import com.arsdigita.web.Web; + +import org.apache.log4j.Logger; + +/** + * Allows definition of new bookmarks to add to the portlet, and edit, move, + * deletion of existing bookmarks. + * + * @author cgyg9330 + */ +public class BookmarksPortletEditor + extends PortletConfigFormSection + implements BookmarkConstants { + + private static final Logger s_log = + Logger.getLogger(BookmarksPortletEditor.class); + + private TextField m_title; + private TextField m_description; + private TextField m_url; + private CheckboxGroup m_newWindow; + + private BookmarksTable m_existingBookmarks; + private BigDecimalParameter m_selectedBookmark; + private BookmarkSelectionModel m_bookmarkSelectionModel; + private BigDecimalParameter m_selectedPortlet; + private PortletSelectionModel m_portletSelectionModel; + + + /** + * + * @param application + */ + public BookmarksPortletEditor(RequestLocal application) { + super(application); + } + + + /** + * store item in requestlocal for access by various methods + * + * code copied from content item portlet - > may be problems when items + * unpublished - check + */ + private RequestLocal contentItem = new RequestLocal() { + @Override + protected Object initialValue(PageState ps) { + String userURL = (String) m_url.getValue(ps); + java.net.URL contextURL; + try { + contextURL = + new java.net.URL( + Web.getRequest().getRequestURL().toString()); + } catch (MalformedURLException ex) { + throw new UncheckedWrapperException(ex); + } + + java.net.URL url; + try { + url = new java.net.URL(contextURL, userURL); + } catch (MalformedURLException ex) { + s_log.info("Malformed URL " + userURL); + return null; + } + + String dp = URL.getDispatcherPath(); + String path = url.getPath(); + if (path.startsWith(dp)) { + path = path.substring(dp.length()); + } + + StringTokenizer tok = new StringTokenizer(path, "/"); + if (!tok.hasMoreTokens()) { + s_log.info( + "Couldn't find a content section for " + + path + + " in " + + userURL); + return null; + } + + String sectionPath = '/' + tok.nextToken() + '/'; + + String context = ContentItem.LIVE; + if (tok.hasMoreTokens() + && CMSDispatcher.PREVIEW.equals(tok.nextToken())) { + + context = CMSDispatcher.PREVIEW; + } + + ContentSectionCollection sections = ContentSection.getAllSections(); + sections.addEqualsFilter(Application.PRIMARY_URL, sectionPath); + + ContentSection section; + if (sections.next()) { + section = sections.getContentSection(); + sections.close(); + } else { + s_log.info( + "Content section " + + sectionPath + + " in " + + userURL + + " doesn't exist."); + return null; + } + + ItemResolver resolver = section.getItemResolver(); + + path = path.substring(sectionPath.length()); + + if (path.endsWith(".jsp")) { + path = path.substring(0, path.length() - 4); + } + + ContentItem item = resolver.getItem(section, path, context); + if (item == null) { + s_log.debug("Couldn't resolve item " + path); + return null; + } + + SecurityManager sm = new SecurityManager(item.getContentSection()); + + boolean canRead = + sm.canAccess( + ps.getRequest(), + SecurityManager.PUBLIC_PAGES, + item); + if (!canRead) { + s_log.debug("User not allowed access to item"); + return null; + + } + + return item.getDraftVersion(); + } + }; + + + /** + * register the parameter that records the current selected bookmark + */ + @Override + public void register (Page p) { + super.register(p); + p.addComponentStateParam(this, m_selectedBookmark); + p.addComponentStateParam(this, m_selectedPortlet); + } + + /** + * + */ + @Override + protected void addWidgets() { + // create widgets + m_url = new TextField(new StringParameter(Link.TARGET_URI)); + m_url.addValidationListener(new NotNullValidationListener()); + + m_title = new TextField(new StringParameter(Link.DISPLAY_NAME)); + m_title.addValidationListener(new NotNullValidationListener()); + + m_description = new TextField(new StringParameter(Link.DESCRIPTION)); + + m_newWindow = new CheckboxGroup(Link.TARGET_WINDOW); + m_newWindow.addOption(new Option(NEW_WINDOW_YES, NEW_WINDOW)); + + try { + m_newWindow.addPrintListener(new PrintListener() { + + public void prepare(PrintEvent e) { + PageState state = e.getPageState(); + CheckboxGroup newWindow = (CheckboxGroup)e.getTarget(); + if (m_bookmarkSelectionModel.isSelected(state)) { + Link link = m_bookmarkSelectionModel.getSelectedLink(state); + newWindow.setValue(state, link.getTargetWindow()); + + } + + } + }); + } catch (IllegalArgumentException e) { + s_log.warn("exception when trying to set checkbox value", e); + } catch (TooManyListenersException e) { + s_log.warn("exception when trying to set checkbox value", e); + } + + + m_selectedPortlet = new BigDecimalParameter("bookmark_portlet"); + m_portletSelectionModel = new PortletSelectionModel(m_selectedPortlet); + m_selectedBookmark = new BigDecimalParameter("bookmark"); + m_bookmarkSelectionModel = new BookmarkSelectionModel( + "uk.gov.westsussex.portlet.bookmarks.Bookmark", + Bookmark.BASE_DATA_OBJECT_TYPE, m_selectedBookmark); + m_existingBookmarks = new BookmarksTable(m_bookmarkSelectionModel, + m_portletSelectionModel); + + super.addWidgets(); + + add(new HorizontalLine(), ColumnPanel.FULL_WIDTH); + + + add(m_existingBookmarks, ColumnPanel.FULL_WIDTH); + add(new HorizontalLine(), ColumnPanel.FULL_WIDTH); + + add(ADD_NEW_BOOKMARK_LABEL, ColumnPanel.FULL_WIDTH); + add(TITLE_LABEL, ColumnPanel.RIGHT); + add(m_title); + add(DESCRIPTION_LABEL, ColumnPanel.RIGHT); + add(m_description); + + + add(URL_LABEL, ColumnPanel.RIGHT); + add(m_url); + add(new Label("")); // fill up the left hand column + add(m_newWindow); + + } + + /** + * specify current portlet for reference by table + * + * fill in values if user has selected edit on an existing bookmark + */ + @Override + protected void initWidgets(PageState state, Portlet portlet) + throws FormProcessException { + s_log.debug("init widgets - set selected portlet to " + portlet.getOID()); + // set cached version as dirty here rather than during process + // in case an action link is pressed (eg to move links up/down) + portlet.getPortletRenderer().invalidateCachedVersion(state); + m_portletSelectionModel.setSelectedObject(state, portlet); + super.initWidgets(state, portlet); + if (m_bookmarkSelectionModel.isSelected(state)) { + Bookmark link = m_bookmarkSelectionModel.getSelectedLink(state); + m_url.setValue(state, BookmarksPortlet.getURIForBookmark(link, state)); + m_description.setValue(state, link.getDescription()); + m_title.setValue(state, link.getTitle()); + + } + } + + /** + * Validates url if it looks like it is trying to be a content item + * but is failing + */ + @Override + public void validateWidgets(PageState state, Portlet portlet) + throws FormProcessException { + // m_selectedPortlet.set(state, portlet); + super.validateWidgets(state, portlet); + + String fullUrl = (String) m_url.getValue(state); + s_log.debug("fullURL = " + fullUrl); + + Object item = contentItem.get(state); + URL here = URL.here(state.getRequest(), null); + String thisSite = here.getServerURI(); + s_log.debug("This site is " + thisSite); + if (item == null && fullUrl.indexOf(thisSite) != -1 + && fullUrl.indexOf("/ccm/") != -1 + && fullUrl.indexOf("/content/") != -1 ) { + // not watertight, but is reasonable check that user is trying + // to specify a content item on this site + throw new FormProcessException(CONTENT_ITEM_NOT_FOUND); + } + + } + /** + * add new bookmark to portlet, or amend existing one if we are editing + * a selected bookmark + */ + @Override + protected void processWidgets(PageState state, Portlet portlet) + throws FormProcessException { + s_log.debug("START processWidgets"); + super.processWidgets(state, portlet); + + + BookmarksPortlet myportlet = (BookmarksPortlet) portlet; + + String titleText = (String) m_title.getValue(state); + String urlText = (String) m_url.getValue(state); + String descriptionText = (String)m_description.getValue(state); + + ContentItem item = (ContentItem) contentItem.get(state); + String[] newWindowValue = (String[]) m_newWindow.getValue(state); + String newWindow = + newWindowValue == null ? NEW_WINDOW_NO : NEW_WINDOW_YES; + + Bookmark newBookmark; + + if (m_bookmarkSelectionModel.isSelected(state)) { + newBookmark = m_bookmarkSelectionModel.getSelectedLink(state); + + } else { + newBookmark = new Bookmark(); + myportlet.addBookmark(newBookmark); + + } + newBookmark.setTitle(titleText); + newBookmark.setDescription(descriptionText); + newBookmark.setTargetWindow(newWindow); + if (item == null) { + newBookmark.setTargetType(Link.EXTERNAL_LINK); + newBookmark.setTargetURI(urlText); + + } else { + newBookmark.setTargetType(Link.INTERNAL_LINK); + newBookmark.setTargetItem(item); + } + + + m_bookmarkSelectionModel.clearSelection(state); + s_log.debug("END processWidgets"); + } + + +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletRenderer.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletRenderer.java new file mode 100644 index 000000000..e1a484c9f --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksPortletRenderer.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package com.arsdigita.portlet.bookmarks.ui; + +import com.arsdigita.portlet.bookmarks.Bookmark; +import com.arsdigita.portlet.bookmarks.BookmarkConstants; +import com.arsdigita.portlet.bookmarks.BookmarksPortlet; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.portal.AbstractPortletRenderer; +// import com.arsdigita.portalworkspace.ui.PortalConstants; +import com.arsdigita.persistence.DataCollection; +import com.arsdigita.portal.PortletType; +import com.arsdigita.xml.Element; + +import org.apache.log4j.Logger; + +/** + * @author cgyg9330 + * + * + */ +public class BookmarksPortletRenderer extends AbstractPortletRenderer + implements BookmarkConstants { + + private static Logger s_log = Logger.getLogger(BookmarksPortletRenderer.class); + + private BookmarksPortlet portlet; + + + /** + * Constructor. + * + * @param portlet + */ + public BookmarksPortletRenderer(BookmarksPortlet portlet) { + this.portlet = portlet; + } + + + /* (non-Javadoc) + * @see com.arsdigita.bebop.portal. + * AbstractPortletRenderer#generateBodyXML( + * com.arsdigita.bebop.PageState, + * com.arsdigita.xml.Element) + */ + protected void generateBodyXML(PageState state, Element document) { + s_log.debug("START generateBodyXML"); + + Element main = document.newChildElement(MAIN_BOOKMARK_PORTLET_ELEMENT, + PortletType.PORTLET_XML_NS); + // PortalConstants.PORTLET_XML_NS); + DataCollection links = portlet.getBookmarks(); + + while (links.next()) { + Bookmark link = new Bookmark (links.getDataObject()); + String url = BookmarksPortlet.getURIForBookmark(link, state); + if (url != null) { + Element linkElement = createLink(link, state); + main.addContent(linkElement); + } + } + + s_log.debug("END generateBodyXML"); + } + + + private Element createLink(Bookmark bookmark, PageState state) { + String url = BookmarksPortlet.getURIForBookmark(bookmark, state); + Element link = new Element(BOOKMARK_ELEMENT, XML_BOOKMARK_NS); + link.addAttribute(TITLE_ATTRIBUTE, bookmark.getTitle()); + link.addAttribute( + URL_ATTRIBUTE, + url); + link.addAttribute(WINDOW_ATTRIBUTE, bookmark.getTargetWindow()); + + return link; + } + + + /** + * cache key is portlet id + */ + @Override + public String getCacheKey(PageState state) { + return portlet.getID().toString(); + } + + /** + * if we are checking permissions, don't use cache, otherwise refresh + * when portlet has been edited + */ + @Override + public boolean isDirty(PageState state) { + if (!BookmarksPortlet.getConfig().checkPermissions()){ +// if cached version exists then it isn't dirty + // because cached version is dropped whenever the portlet is edited + // (see init method in editor class) + return false; + } else { + return true; + + } + + } +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTable.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTable.java new file mode 100644 index 000000000..32ce9ccb9 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTable.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2005 Chris Gilbert All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package com.arsdigita.portlet.bookmarks.ui; + + +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.ExternalLink; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.event.TableActionEvent; +import com.arsdigita.bebop.event.TableActionListener; +import com.arsdigita.bebop.portal.PortletSelectionModel; +import com.arsdigita.bebop.table.TableCellRenderer; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableColumnModel; +import com.arsdigita.cms.contenttypes.ui.LinkTableModelBuilder; +import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.domain.DomainObjectFactory; +import com.arsdigita.persistence.OID; +import com.arsdigita.persistence.PersistenceException; +import com.arsdigita.portlet.bookmarks.Bookmark; +import com.arsdigita.portlet.bookmarks.BookmarksPortlet; +import com.arsdigita.util.Assert; +import com.arsdigita.util.UncheckedWrapperException; + +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + + +/** + * Bebop table copied from authoring ui + * + * @version $Revision: 1.2 $ $Date: 2007/08/08 09:28:26 $ + * @author Chris Gilbert + */ +public class BookmarksTable extends Table { + + private static final Logger s_log = Logger.getLogger(BookmarksTable.class); + + private BookmarkSelectionModel m_linkModel; + // private ItemSelectionModel m_itemModel; + private TableColumn m_titleCol; + private TableColumn m_descCol; + private TableColumn m_moveUpCol; + private TableColumn m_moveDownCol; + private TableColumn m_editCol; + private TableColumn m_delCol; + + private RequestLocal m_size; + private PortletSelectionModel m_portlet; + + + protected static final String EDIT_EVENT = "Edit"; + protected static final String DELETE_EVENT = "Delete"; + protected static final String UP_EVENT = "up"; + protected static final String DOWN_EVENT = "down"; + + /** + * Constructor. Creates a BookmarksTable given a + * PortletSelectionModel and a + * BookmarkSelectionModel, which track the current portlet + * and link. + * + * @param item The ItemSelectionModel for the current page. + * @param link The LinkSelectionModel to track the + * current link + */ + public BookmarksTable(BookmarkSelectionModel link, PortletSelectionModel portlet) { + super(); + m_portlet = portlet; + setModelBuilder(new BookmarksTableModelBuilder(portlet)); + + m_linkModel = link; + addColumns(); + + m_size = new RequestLocal(); + + Label empty = new Label("There are no links defined yet"); + setEmptyView(empty); + addTableActionListener(new LinkTableActionListener()); + setRowSelectionModel(m_linkModel); + setDefaultCellRenderer(new LinkTableRenderer()); + } + + /** + * Sets up the columns to display. + */ + protected void addColumns() { + TableColumnModel model = getColumnModel(); + int i = 0; + m_titleCol = new TableColumn(i, "Link"); + m_descCol = new TableColumn(++i, "Description"); + m_editCol = new TableColumn(++i, "Edit"); + m_delCol = new TableColumn(++i, "Delete"); + m_moveUpCol = new TableColumn(++i, ""); + m_moveDownCol = new TableColumn(++i, ""); + model.add(m_titleCol); + model.add(m_descCol); + model.add(m_editCol); + model.add(m_delCol); + model.add(m_moveUpCol); + model.add(m_moveDownCol); + setColumnModel(model); + } + + /** + * TableCellRenderer class for LinkTable + */ + private class LinkTableRenderer implements TableCellRenderer { + public Component getComponent(Table table, + PageState state, + Object value, + boolean isSelected, + Object key, + int row, + int column) { + Bookmark link = (Bookmark)value; + boolean isFirst = (row == 0); + if (m_size.get(state) == null) { + m_size.set(state, + new Long(((LinkTableModelBuilder.LinkTableModel) + table.getTableModel(state)).size())); + } + boolean isLast = (row == ((Long)m_size.get(state)).intValue() - 1); + + String url = BookmarksPortlet.getURIForBookmark(link, state);//link.getInternalOrExternalURI(state); + ExternalLink extLink = null; + if (column == m_titleCol.getModelIndex()) { + if (null != url) { + extLink = new ExternalLink(link.getTitle(), url); + extLink.setTargetFrame(link.getTargetWindow()); + } else { + extLink = new ExternalLink("Broken Link", url); + + } + return extLink; + } else if ( column == m_descCol.getModelIndex()) { + if ( isSelected ) { + return new Label(url == null? "Page has been unpublished" : link.getDescription(), Label.BOLD); + } else { + return new Label(url == null? "Page has been unpublished" : link.getDescription()); + } + } else if ( column == m_editCol.getModelIndex()) { + if (isSelected ) { + return new Label(EDIT_EVENT, Label.BOLD); + } else { + return new ControlLink(EDIT_EVENT); + } + + } else if ( column == m_delCol.getModelIndex()) { + return new ControlLink(DELETE_EVENT); + + } else if (column == m_moveUpCol.getModelIndex()) { + if (!isFirst) { + Label upLabel = new Label(UP_EVENT); + upLabel.setClassAttr("linkSort"); + return new ControlLink(upLabel); + } else { + return new Label(""); + } + } else if (column == m_moveDownCol.getModelIndex()) { + if (!isLast) { + Label downLabel = new Label(DOWN_EVENT); + downLabel.setClassAttr("linkSort"); + return new ControlLink(downLabel); + } else { + return new Label(""); + } + } else { + throw new UncheckedWrapperException("column out of bounds"); + } + } + } + + /** + * TableActionListener class for LinkTable + */ + private class LinkTableActionListener implements TableActionListener { + private Bookmark getLink(TableActionEvent e) { + Object o = e.getRowKey(); + BigDecimal id; + if (o instanceof String) { + s_log.debug("row key is a string : " + o); + id = new BigDecimal((String)o); + } else { + id = (BigDecimal)e.getRowKey(); + } + + Assert.exists(id); + Bookmark link; + try { + link = (Bookmark)DomainObjectFactory.newInstance(new OID(Bookmark.BASE_DATA_OBJECT_TYPE,id)); + } catch (DataObjectNotFoundException de) { + throw new UncheckedWrapperException(de); + } + return link; + } + + public void cellSelected(TableActionEvent e) { + int col = e.getColumn().intValue(); + PageState state = e.getPageState(); + Bookmark link = getLink(e); + Assert.exists(link); + + if (col== m_titleCol.getModelIndex()) { + // do nothing + } else if (col == m_editCol.getModelIndex()) { + // This selection is passed to the LinkPropertyForm + s_log.debug("setting linkModel to :" + link.getTitle()); + m_linkModel.setSelectedObject(state, link); + + } else if (col == m_delCol.getModelIndex()) { + try { + s_log.debug("About to delete"); + m_linkModel.clearSelection(state); + link.delete(); + BookmarksPortlet portlet = (BookmarksPortlet)m_portlet.getSelectedPortlet(state); + portlet.renumberBookmarks(); + } catch ( PersistenceException pe) { + throw new UncheckedWrapperException(pe); + } + + } else if (col == m_moveUpCol.getModelIndex() ) { + // move the link up + m_linkModel.clearSelection(state); + link.swapWithPrevious(); + } else if ( col == m_moveDownCol.getModelIndex() ) { + // move the link down + m_linkModel.clearSelection(state); + link.swapWithNext(); + } + } + + public void headSelected(TableActionEvent e) {} + } +} diff --git a/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTableModelBuilder.java b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTableModelBuilder.java new file mode 100644 index 000000000..0d6fecc61 --- /dev/null +++ b/ccm-portlet-bookmarks/src/com/arsdigita/portlet/bookmarks/ui/BookmarksTableModelBuilder.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2004 Red Hat Inc. All Rights Reserved. + * + * The contents of this file are subject to the Open Software License v2.1 + * (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://rhea.redhat.com/licenses/osl2.1.html. + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + */ +package com.arsdigita.portlet.bookmarks.ui; + +import org.apache.log4j.Logger; + +import com.arsdigita.portlet.bookmarks.BookmarksPortlet; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.portal.PortletSelectionModel; +import com.arsdigita.cms.contenttypes.ui.LinkTableModelBuilder; +import com.arsdigita.persistence.DataCollection; + +/** + * Copied from authoting UI + * + * @version $Revision: 1.3 $ $Date: 2007/08/08 09:28:26 $ + * @author Chris Gilbert + */ + +public class BookmarksTableModelBuilder + extends LinkTableModelBuilder { + private static final Logger s_log = + Logger.getLogger(BookmarksTableModelBuilder.class); + + private PortletSelectionModel m_portlet; + + /** + * Constructor. Creates a BookmarksTableModelBuilder given a + * PortletSelectionModel + * + * @param portlet The PortletSelectionModel that refers to the current portlet. + * + */ + public BookmarksTableModelBuilder(PortletSelectionModel portlet) { + m_portlet = portlet; + s_log.debug("BookmarksTableModelBuilder"); + } + + /** + * Returns the DataCollection of Bookmarks for the current + * TableModel. + * + * @param s The PageState for the current request + * @return The DataCollection of Bookmarks + */ + public DataCollection getLinks(PageState state) { + BookmarksPortlet portlet = (BookmarksPortlet)m_portlet.getSelectedPortlet(state); + s_log.debug("Getting related links for " + portlet.getOID()); + return portlet.getBookmarks(); + + } +} diff --git a/ccm-portlet-bookmarks/web/themes/heirloom/images/portlets/arrow_bullet.gif b/ccm-portlet-bookmarks/web/themes/heirloom/images/portlets/arrow_bullet.gif new file mode 100644 index 0000000000000000000000000000000000000000..1e385a5c091c4c40c75b8ecb71f14fcd2488e3d4 GIT binary patch literal 67 zcmZ?wbhEHb6k!lyXkcKN$-wac|9{1wEUY37j0`#q3=9k)83rb)p8l1m-|{b>Bf=DL W_-xE$-P{E6-pQWJUU`W!SOWlA(iAcP literal 0 HcmV?d00001 diff --git a/ccm-portlet-bookmarks/web/themes/heirloom/portlets/bookmarks-portlet.xsl b/ccm-portlet-bookmarks/web/themes/heirloom/portlets/bookmarks-portlet.xsl new file mode 100644 index 000000000..bdf8ee33b --- /dev/null +++ b/ccm-portlet-bookmarks/web/themes/heirloom/portlets/bookmarks-portlet.xsl @@ -0,0 +1,40 @@ + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + | + + + + + + + +
\ No newline at end of file