Author: chrisg23 Date: 2007-09-17 12:00:38 +0200 (Mon, 17 Sep 2007) New Revision: 1635 Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/application.xml aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/TermDate.pdl aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/navigation/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/navigation/Category.pdl aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/query-missing-notification-phases.pdl aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.config aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.load aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.upgrade aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CookieManager.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CredentialLoginModule.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/UserLoginModule.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepagePortalSelectionModel.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspace.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspaceSelectionModel.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/cms/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/cms/workflow/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/cms/workflow/DeployTaskURLGenerator.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/CategorySpecificNavigationModel.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/Initializer.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/TermDate.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/UnpublishNotification.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/Util.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/WSGfLConfig.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/WSGfLConfig_parameter.properties aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/WSGfLCustom.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/WSGfLResourceBundle.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/WSGfLResources.properties aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/data/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/data/DatabaseConnection.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/CEDAgencyInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/CEDEstablishmentInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/CEDSchoolInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/CEDUnitInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/DominoSchoolInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/EducationEstablishment.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/EstablishmentInformationAdapter.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/EstablishmentInformationProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/EstablishmentListener.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/data/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/data/CEDEstablishmentDAO.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/establishment/data/CEDEstablishmentData.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/AddTermDates.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/ConvertJiveForum.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/CreateMissingNotificationPhases.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/RSSPortletLoad.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/RemoveExcessTasks.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/RemoveWorkflows.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/jobs/SendTestEmails.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/Menu.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/NavigationFileResolver.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/Path.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/PopulatedSubcategoryTreeCatProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/navigation/SkipLevelTreeCatProvider.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/DynamicLink.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/LoginHelper.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/SubsiteDispatcher.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/SubsiteResources_en.properties aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/SubsiteResources_fr.properties aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/wsgfl/ui/login/UserRegistrationForm.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/UtilitiesTest.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/WSGfLCaseTestSetup.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/WSGfLTestCaseSuite.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/utilities/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/test/src/uk/gov/westsussex/wsgfl/utilities/HttpUnitTestCase.java aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/WEB-INF/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/WEB-INF/web.xml.wsgfl aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/favicon.ico aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/javascript/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/javascript/CalendarPopup.js aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/javascript/emergency-contacts.js aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/javascript/lmdu.js aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/content-section/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/content-section/templates/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/content-section/templates/default/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/content-section/templates/default/non-cached-aplaws-item.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/wsx/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/wsx/templates/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/wsx/templates/access-controlled-navigation.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/wsx/templates/access-controlled-navigation.jsp.orig aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/packages/wsx/templates/access-controlled-portal-navigation.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/robots.txt aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/admin/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/admin/index.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/admin/sitemap.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/edit.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/index.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/templates/ccm-wsx-portal/portal/workspaces.jsp aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/wsgfl-assets/ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/web/wsgfl-assets/redirect.htm Log: Custom Code for West Sussex Grid for Learning - includes generic Estabishment lookup used by other applications Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/application.xml =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/application.xml (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/application.xml 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + +<ccm:application name="ccm-wsx-wsgfl-custom" + prettyName="WSGfL Custom Code" + version="1.0.2" + release="1" + webapp="ROOT" + xmlns:ccm="http://ccm.redhat.com/ccm-project"> + + <ccm:dependencies> + <ccm:requires name="ccm-ldn-portal" version="1.4.2"/> + </ccm:dependencies> + <ccm:directories> + <ccm:directory name="pdl"/> + <ccm:directory name="web"/> + <ccm:directory name="src"/> + </ccm:directories> + + <ccm:contacts> + <ccm:contact uri="http://www.redhat.com/software/rhea" type="website"/> + <ccm:contact uri="mailto:rh...@re..." type="support"/> + </ccm:contacts> + + <ccm:description> + Code that is specific to the WSGfL + </ccm:description> + +</ccm:application> Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/TermDate.pdl =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/TermDate.pdl (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/TermDate.pdl 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,14 @@ +model uk.gov.westsussex; + +import com.arsdigita.kernel.ACSObject; + + +object type TermDate extends ACSObject { + Date [1..1] startDate = term_dates.start_date TIMESTAMP; + Date[1..1] endDate = term_dates.end_date TIMESTAMP; + String [1..1] academicYear = term_dates.academic_year VARCHAR(255); + String [1..1] termName = term_dates.term_name VARCHAR(255); + + reference key (term_dates.term_id); + unique(academicYear, termName); +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/navigation/Category.pdl =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/navigation/Category.pdl (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/navigation/Category.pdl 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,101 @@ + +model uk.gov.westsussex.navigation; + +import com.arsdigita.kernel.ACSObject; +import com.arsdigita.categorization.Category; + +query PopulatedSubcategories { + ACSObject objectInSubCat; + Category subCat; + options { + WRAP_QUERIES = false; + } + + do { + + select a.object_id, + a.object_type, + a.display_name, + a.default_domain_class, + c.category_id, + c.description, + c.name, + c.url, + c.enabled_p, + c.abstract_p, + c.default_ancestors + from acs_objects a, + acs_objects b, + cat_categories c, + cat_object_category_map d, + cat_category_category_map e, + cms_items f + where e.category_id = :categoryID + and c.category_id = e.related_category_id + and b.object_id = c.category_id + and d.category_id = e.related_category_id + and e.relation_type = 'child' + and a.object_id = d.object_id + and f.item_id(+) = a.object_id + and nvl(f.version, 'live') = 'live' + } map { + objectInSubCat.id = a.object_id; + objectInSubCat.objectType = a.object_type; + objectInSubCat.displayName = a.display_name; + objectInSubCat.defaultDomainClass = a.default_domain_class; + subCat.id = b.object_id; + subCat.objectType = b.object_type; + subCat.displayName = b.display_name; + subCat.defaultDomainClass = b.default_domain_class; + subCat.description = c.description; + subCat.name = c.name; + subCat.url = c.url; + subCat.isEnabled = c.enabled_p; + subCat.isAbstract = c.abstract_p; + subCat.defaultAncestors = c.default_ancestors; + + + } +} + + +// copied from Atomwide application - used here to find groups for role groupings during initialisation +// config specifies role groupings, we need to find groups associated both with that role grouping, and the 'all schools' term +// use for in subqueries eg +// select * from groups g +// where g.group_id in (select object_id from CAT_OBJECT_CATEGORY_MAP where category_id = 21385) +// and g.group_id in (select object_id from CAT_OBJECT_CATEGORY_MAP where category_id = 22701) +// to find the group categorised under a particular school AND a particular role grouping +query ObjectsForCategory { + BigDecimal objectID; + options { + WRAP_QUERIES = false; + } + + do { + select object_id + from CAT_OBJECT_CATEGORY_MAP + where category_id = :catID + } map { + objectID = object_id; + } +} + + +// oh dear - if I try to do the above, the persistance layer cannot distinguish between +// the 2 different bind variables called catID, so I need to have 2 queries +query ObjectsForCategory2 { + BigDecimal objectID; + options { + WRAP_QUERIES = false; + } + + do { + select object_id + from CAT_OBJECT_CATEGORY_MAP + where category_id = :catID2 + } map { + objectID = object_id; + } +} + Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/query-missing-notification-phases.pdl =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/query-missing-notification-phases.pdl (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/pdl/uk/gov/westsussex/query-missing-notification-phases.pdl 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,27 @@ + +model uk.gov.westsussex.wsgfl; + +query DeficientCycles { + BigDecimal cycleID; + options { + WRAP_QUERIES = false; + } + + do { + + select a.cycle_id from lifecycles a, + cms_pages b, + acs_object_lifecycle_map c + where a.cycle_id = c.cycle_id + and b.item_id = c.item_id + and a.end_date_time is not null + and not exists (select 1 from phases x, phase_definitions y + where x.cycle_id = a.cycle_id + and x.definition_id = y.phase_definition_id + and y.label = 'expirationImminent') + + + } map { + cycleID = a.cycle_id; + } +} \ No newline at end of file Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.config =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.config (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.config 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<registry> + <config class="uk.gov.westsussex.wsgfl.WSGfLConfig" + storage="ccm-wsx-wsgfl-custom/wsgfl.properties"/> +</registry> Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.load =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.load (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.load 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,11 @@ +<load> + <requires> + <table name="inits"/> + <table name="acs_objects"/> + <initializer class="com.arsdigita.core.Initializer"/> + + </requires> + <provides> + <initializer class="uk.gov.westsussex.wsgfl.Initializer"/> + </provides> +</load> Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.upgrade =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.upgrade (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/ccm-wsx-wsgfl-custom.upgrade 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,6 @@ +<upgrade> + <version from="1.0.1" to="1.0.2"> + <script sql="ccm-wsx-wsgfl-custom/upgrade/::database::-1.0.1-1.0.2.sql"/> + </version> + +</upgrade> Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CookieManager.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CookieManager.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CookieManager.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2001-2004 Red Hat Inc. 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.kernel.security; + +import com.arsdigita.kernel.Kernel; +import com.arsdigita.util.ServletUtils; +import com.arsdigita.util.UncheckedWrapperException; + +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import javax.servlet.http.Cookie; + +import org.apache.log4j.Logger; + +/** + * Manages a string value stored in a cookie. + * + * @see CookieLoginModule + * + * @author Sameer Ajmani + **/ +public class CookieManager extends CredentialManager { + + public static final String versionId = "$Id: CookieManager.java 1477 2007-03-14 10:27:16Z chrisgilbert23 $ by $Author: chrisgilbert23 $, $DateTime: 2004/08/16 18:10:38 $"; + private static final Logger s_log = + Logger.getLogger(CookieManager.class.getName()); + + public void initialize(CredentialLoginModule module, + Subject subject, + CallbackHandler handler, + Map shared, + Map options) { + super.initialize(module, subject, handler, shared, options); + } + + /** + * Determines whether <code>setValue()</code> should be called. + * + * @param value the new value for the credential + * + * @return <code>true</code> if the credential is not set or has the + * wrong value or should be renewed, <code>false</code> otherwise. + **/ + protected boolean shouldSetValue(String value) + throws LoginException { + if (getModule().requestIsExcluded()) { + return false; + } + return !getModule().credentialIsSet() + || !getModule().credentialHasValue(value) + || getModule().credentialIsOld(); + } + + /** + * Returns the value of the cookie named + * <code>getModule().getCredentialName()</code>. + * + * @return the value of the cookie named + * <code>getModule().getCredentialName()</code>. + * + * @throws CredentialNotFoundException if the cookie is not in the + * current request. + * + * @throws LoginException if an error occurs. + **/ + protected final String getValue() + throws LoginException { + s_log.debug("START getValue"); + String value = ServletUtils.getCookieValue + (getModule().getRequest(), + getModule().getCredentialName()); + if (value == null) { + s_log.debug("FAILURE getValue"); + throw new CredentialNotFoundException(); + } + s_log.debug("SUCCESS getValue: "+value); + return value; + } + + /** + * Sets the cookie named <code>getModule().getCredentialName()</code> to + * the given value. + * + * @throws LoginException if an error occurs. + **/ + protected final void setValue(String value) + throws LoginException { + // now we don't automatically set the duration to getCookieMaxAge() + // setCookie(getModule().getCredentialName(), value, getCookieAge()); + // yes we do - cookie age was correctly set to either forever, or + // -1 (exists for duration of browser session). The config parameter + // for cookie duration needs to apply to the credential timestamp + // in order for correct behaviour - This change has been applied + // in UserLoginModule - chr...@we... + setCookie(getModule().getCredentialName(), value, getCookieMaxAge()); + } + + /** + * Deletes the cookie named + * <code>getModule().getCredentialName()</code>. + * + * @throws LoginException if an error occurs. + **/ + protected final void deleteValue() + throws LoginException { + deleteCookie(getModule().getCredentialName()); + } + + /** + * Deletes the named cookie. + **/ + private void deleteCookie(String name) + throws LoginException { + if (isCookieSet(name)) { + s_log.debug("deleting existing cookie"); + setCookie(name, "", 0); // maxAge == 0 deletes cookie + } else { + s_log.debug("Not deleting cookie since it doesn't exist!"); + } + } + + private boolean isCookieSet(String name) { + Cookie cookies[] = null; + try { + cookies = getModule().getRequest().getCookies(); + } catch (LoginException ex) { + throw new UncheckedWrapperException(ex); + } + + if (cookies == null) + return false; + + for (int i = 0 ; i < cookies.length ; i++) + if (cookies[i].getName().equals(name)) + return true; + + return false; + } + + /** + * Sets the named cookie to the given value. + **/ + private void setCookie(String name, String value, int maxAge) + throws LoginException { + Cookie cookie = new Cookie(name, value); + cookie.setMaxAge(maxAge); + cookie.setPath("/"); +// cookie.setSecure(getModule().isSecure()); + cookie.setSecure(false); + getModule().getResponse().addCookie(cookie); + String domain = Kernel.getSecurityConfig().getCookieDomain(); + if (domain != null) { + cookie.setDomain(domain); + } + s_log.debug("Cookie set: domain - " + cookie.getDomain() + + " name - " + cookie.getName()); + } + + /** + * Determines the lifespan of the cookie, using the setting + * of the configuration, defaulting to getCookieMaxAge(). + **/ + protected int getCookieAge() throws LoginException { + Integer setting = Kernel.getSecurityConfig().getCookieDurationMinutes(); + return (setting == null ? getCookieMaxAge() : setting.intValue() * 60); + } + + /** + * Determines the correct max age for the cookie in seconds. A return + * value of -1 means the cookie should be deleted when the client's + * browser quits. + * + * @return <code>FOREVER_SECS</code> if the user has requested permanent + * login; -1 otherwise. + **/ + protected int getCookieMaxAge() throws LoginException { + return getModule().getForever() ? + (int)CredentialLoginModule.FOREVER_SECS : -1; + } +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CredentialLoginModule.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CredentialLoginModule.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/CredentialLoginModule.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2001-2004 Red Hat Inc. 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.kernel.security; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import com.arsdigita.kernel.Kernel; + +/** + * Loads an ID from a credential stored in the current HTTP request (for + * example, cookie or URL parameter). If the credential is invalid but the + * ID is loaded successfully using another <code>LoginModule</code>, this + * module sets a new credential containing the ID. This class uses the + * <i>Strategy</i> design pattern to manage the persistent credential value; + * it delegates to the <code>CredentialManager</code> provided at + * construction to get, set, and delete the credential value. + * + * @see CredentialManager + * + * @author Sameer Ajmani + **/ +public abstract class CredentialLoginModule implements LoginModule { + + public static final String versionId = "$Id: CredentialLoginModule.java 718 2005-08-18 15:34:42Z apevec $ by $Author: apevec $, $DateTime: 2004/08/16 18:10:38 $"; + private static final Logger s_log = + Logger.getLogger(CredentialLoginModule.class.getName()); + + /** + * Minimum time allowed between session renewals, in seconds. + **/ + public static final long RENEW_SECS = 60*5; // 5 mins + + /** + * Maximum time allowed between clicks in a single session, in seconds. + **/ + public static final long TIMEOUT_SECS = 60*20; // 20 mins + + /** + * Maximum time that a single session can last, in seconds. + **/ + public static final long LIFETIME_SECS = 60*60*24*2; // 2 days + + /** + * Maximum time that a "permanent" credential can last, in seconds. + **/ + public static final long FOREVER_SECS = 60*60*24*365*3; // 3 years + + // fields set by initialize() + private Subject m_subject; + private CallbackHandler m_handler; + private Map m_shared; + private Map m_options; + + // cached values for accessors + private HttpServletRequest m_req = null; + private HttpServletResponse m_res = null; + private Boolean m_forever = null; + private Boolean m_secure = null; + + // the credential itself + private Credential m_credential = null; + + // manages the credential value + private CredentialManager m_manager; + + /** + * Creates a new <code>CredentialLoginModule</code> associated with the + * given <code>CredentialManager</code>. This module uses the given + * manager to get, set, and delete the credential value. + **/ + public CredentialLoginModule(CredentialManager manager) { + m_manager = manager; + } + + /** + * Initializes this login module and its <code>CredentialManager</code> + * with the given login context information. This method is called by + * <code>LoginContext</code> after this class is instantiated. + **/ + public void initialize(Subject subject, + CallbackHandler handler, + Map shared, + Map options) { + m_manager.initialize(this, subject, handler, shared, options); + m_subject = subject; + m_handler = handler; + m_shared = shared; + m_options = options; + } + + /** + * Checks whether the current request contains a valid credential. + * + * @return <code>true<code>. + * @throws CredentialNotFoundException if the credential is missing. + * @throws CredentialParsingException if the credential is invalid. + * @throws CredentialExpiredException if the credential has expired. + * @throws LoginException if an error occurs. + **/ + public boolean login() throws LoginException { + s_log.debug("START login"); + loadCredential(); + s_log.debug("END login"); + return true; + } + + /** + * Deletes the credential and invalidates the client session. + * + * @return <code>true</code>. + * @throws LoginException if an error occurs. + **/ + public boolean logout() throws LoginException { + s_log.debug("START logout"); + invalidateSession(); + deleteCredential(); + s_log.debug("END logout"); + return true; + } + + /** + * Deletes the credential. + * + * @return true + * @throws LoginException if an error occurs + **/ + public boolean abort() throws LoginException { + // overall login failed + s_log.debug("START abort"); + deleteCredential(); + s_log.debug("END abort"); + return true; + } + + /** + * Sets the ID for the Subject to the value of the credential if no ID + * is already set. If needed, updates the credential. If the Subject + * has an ID different from the one in the credential, invalidates the + * client session. + * + * @return <code>true</code>. + * @throws FailedLoginException if unable to set ID. + * @throws LoginException if an error occurs. + **/ + public boolean commit() throws LoginException { + // overall login succeeded + s_log.debug("START commit"); + try { + BigDecimal id = getID(); + String value = id.toString(); + if (shouldInvalidateSession(value)) { + invalidateSession(); + } + if (m_manager.shouldSetValue(value)) { + setCredential(value); + } + s_log.debug("SUCCESS commit"); + } catch (FailedLoginException e) { + // ignore failure, because another LoginModule may succeed + s_log.debug("FAILURE commit (ignored)", e); + } + return true; + } + + /** + * Reads the ID from the Subject and sets it if needed. First, checks + * if some other LoginModule has assigned an ID to the Subject. If not, + * reads the ID from the credential and sets it in the Subject. + * + * @return the ID. + * @throws FailedLoginException if the ID is not available. + **/ + private BigDecimal getID() + throws FailedLoginException { + s_log.debug("START getID"); + try { + // load ID from subject + BigDecimal id = loadID(); + s_log.debug("SUCCESS getID from subject"); + return id; + } catch (NoSuchElementException e) { + // load ID from credential + if (!credentialIsSet()) { + s_log.debug("FAILURE getID not available", e); + throw new FailedLoginException("No ID available"); + } + try { + String value = m_credential.getValue(); + BigDecimal id = new BigDecimal(value); + s_log.debug("SUCCESS getID from credential"); + saveID(id); + return id; + } catch (NumberFormatException nfe) { + s_log.debug("FAILURE getID number format", nfe); + throw new FailedLoginException("No ID available"); + } + } + } + + /** + * Loads the ID from the Subject. + **/ + protected final BigDecimal loadID() + throws NoSuchElementException { + Set set = m_subject.getPrincipals(PartyPrincipal.class); + return ((PartyPrincipal)set.iterator().next()).getID(); + } + + /** + * Saves the given ID in the Subject. + * + * @param id the ID to save + **/ + protected final void saveID(BigDecimal id) { + m_subject.getPrincipals().add(new PartyPrincipal(id)); + } + + /** + * Determines whether the current request is secure. + * + * @return <code>true</code> if the current request is secure, + * <code>false</code> otherwise. + * + * @throws LoginException if an error occurs. + **/ + protected final boolean isSecure() + throws LoginException { + if (m_secure == null) { + m_secure = new Boolean + (Util.getSecurityHelper().isSecure(getRequest())); + } + return m_secure.booleanValue(); + } + + /** + * Returns the name of the credential. + * @return the name of the credential. + * @throws LoginException if an error occurs. + **/ + protected abstract String getCredentialName() + throws LoginException; + + /** + * Returns the lifetime of the credential in milliseconds. + * @return the lifetime of the credential in milliseconds. + * @throws LoginException if an error occurs. + **/ + protected abstract long getLifetime() + throws LoginException; + + /** + * Loads the credential. + **/ + private void loadCredential() throws LoginException { + s_log.debug("START loadCredential"); + String value = m_manager.getValue(); + m_credential = Credential.parse(value); + s_log.debug("SUCCESS loadCredential: expires: " + +m_credential.getExpiration()); + } + + /** + * Determines whether the client session should be invalidated. + * + * @param value the new value for the credential + * + * @return <code>true</code> if the client session should be + * invalidated, <code>false</code> otherwise. + * + * @throws LoginException if an error occurs. + **/ + protected abstract boolean shouldInvalidateSession(String value) + throws LoginException; + + /** + * Invalidates the client session and creates a new one. + **/ + private void invalidateSession() + throws LoginException { + s_log.debug("invalidateSession: before: " + +getRequest().getSession().getId()); + + getRequest().getSession().invalidate(); + getRequest().getSession(); // create new session + + s_log.debug("invalidateSession: after: " + +getRequest().getSession().getId()); + } + + /** + * Sets the credential value to the given value. + **/ + private void setCredential(String value) + throws LoginException { + s_log.debug("START setCredential to "+value); + m_credential = Credential.create(value, getLifetime()); + m_manager.setValue(m_credential.toString()); + s_log.debug("SUCCESS setCredential: expires: " + +m_credential.getExpiration()); + } + + /** + * Determines whether the credential is set. Subclasses may call this + * to determine whether this login module succeeded. + * + * @return <code>true</code> if credential is set, <code>false</code> + * otherwise. + **/ + protected final boolean credentialIsSet() { + return (m_credential != null); + } + + /** + * Determines whether the credential has the given value. + * + * @param value the value to check + * + * @return <code>true</code> if credential's value equals the given + * value, <code>false</code> otherwise. + * + * @throws NullPointerException if !credentialIsSet(). + **/ + protected final boolean credentialHasValue(String value) { + return m_credential.getValue().equals(value); + } + + /** + * Determines whether the credential should be renewed. Returns + * <code>true</code> if the credential is more than + * <code>RENEW_SECS</code> old. + * + * @return <code>true</code> if credential is old; <code>false</code> + * otherwise. + * + * @throws NullPointerException if !credentialIsSet(). + **/ + protected final boolean credentialIsOld() { + long expireTime = m_credential.getExpiration().getTime() / 1000; + long issueTime = expireTime - TIMEOUT_SECS; + long renewTime = issueTime + RENEW_SECS; + long currentTime = System.currentTimeMillis() / 1000; + return renewTime < currentTime; + } + + /** + * Determines whether the requested URI ends in an "excluded" extension. + * Extensions in the "excluded" list specify file types for which + * credentials should never be set, such as image and media files. + * + * @return <code>true</code> if the request URI ends with an "excluded" + * extension, <code>false</code> otherwise. + * + * @throws LoginException if an error occurs. + **/ + protected final boolean requestIsExcluded() + throws LoginException { + java.util.Iterator exts = Initializer.getExcludedExtensions(); + while (exts.hasNext()) { + String ext = (String)exts.next(); + if (getRequest().getRequestURI().endsWith(ext)) { + s_log.debug("got excluded extension: " + +getRequest().getRequestURI()); + return true; + } + } + return false; + } + + /** + * Deletes the credential. + **/ + private void deleteCredential() + throws LoginException { + m_manager.deleteValue(); + m_credential = null; + } + + /** + * Returns the current HTTP request. + * + * @return the current HTTP request. + * + * @throws LoginException if an error occurs. + **/ + protected final HttpServletRequest getRequest() + throws LoginException + { + if (m_req == null) { + m_req = Util.getRequest(m_handler); + } + return m_req; + } + + /** + * Returns the current HTTP response. + * + * @return the current HTTP response. + * + * @throws LoginException if an error occurs. + **/ + protected final HttpServletResponse getResponse() + throws LoginException { + try { + if (m_res == null) { + HTTPResponseCallback cb = new HTTPResponseCallback(); + m_handler.handle(new Callback[] { cb }); + m_res = cb.getResponse(); + } + return m_res; + } catch (IOException e) { + throw new KernelLoginException + ("Could not get HTTP response", e); + } catch (UnsupportedCallbackException e) { + throw new KernelLoginException + ("Could not get HTTP response", e); + } + } + + /** + * Determines whether the credential should last "forever" or should + * expire at the end of this session. + * + * @return <code>true</code> if the credential should last "forever", + * <code>false</code> if the credential should expire at the end of this + * session. + * + * @throws KernelLoginException if an error occurs. + **/ + protected final boolean getForever() throws LoginException { + try { + if (m_forever == null) { + LifetimeCallback cb = new LifetimeCallback(); + m_handler.handle(new Callback[] { cb }); + m_forever = new Boolean(cb.isForever()); + } + return m_forever.booleanValue(); + } catch (IOException e) { + throw new KernelLoginException("Could not get lifetime", e); + } catch (UnsupportedCallbackException e) { + throw new KernelLoginException("Could not get lifetime", e); + } + } +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/UserLoginModule.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/UserLoginModule.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/com/arsdigita/kernel/security/UserLoginModule.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2001-2004 Red Hat Inc. 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.kernel.security; + +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import org.apache.log4j.Logger; + +import com.arsdigita.kernel.Kernel; + +/** + * Authenticates a user (loads a user ID) from a credential stored in the + * current HTTP request. + * + * @author Sameer Ajmani + **/ +public abstract class UserLoginModule extends CredentialLoginModule { + + public static final String versionId = "$Id: UserLoginModule.java 1477 2007-03-14 10:27:16Z chrisgilbert23 $ by $Author: chrisgilbert23 $, $DateTime: 2004/08/16 18:10:38 $"; + private static final Logger s_log = + Logger.getLogger(UserLoginModule.class.getName()); + + /** + * Name of the non-secure user authentication credential. + **/ + public static final String NORMAL_CREDENTIAL_NAME + = "ad_user_login"; + + /** + * Name of the secure user authentication credential. + **/ + public static final String SECURE_CREDENTIAL_NAME + = "ad_user_login"; + + // fields set by initialize() + private Subject m_subject; + private CallbackHandler m_handler; + private Map m_shared; + private Map m_options; + + public UserLoginModule(CredentialManager manager) { + super(manager); + } + + // implements LoginModule + public void initialize(Subject subject, + CallbackHandler handler, + Map shared, + Map options) { + super.initialize(subject, handler, shared, options); + m_subject = subject; + m_handler = handler; + m_shared = shared; + m_options = options; + } + + /** + * Returns the name of the credential. + * + * @return <code>SECURE_CREDENTIAL_NAME</code> if the current request is + * secure, otherwise returns <code>NORMAL_CREDENTIAL_NAME</code>. + **/ + protected String getCredentialName() + throws LoginException { + if (isSecure()) { + return SECURE_CREDENTIAL_NAME; + } else { + return NORMAL_CREDENTIAL_NAME; + } + } + + /** + * Returns the lifetime of the credential in milliseconds. + * + * @return <code>FOREVER_SECS</code> in milliseconds if the user + * requests permanent login, otherwise returns <code>TIMEOUT_SECS</code> + * in milliseconds. + **/ + protected long getLifetime() throws LoginException { + Integer setting = Kernel.getSecurityConfig().getCookieDurationMinutes(); + long longSetting = setting == null ? TIMEOUT_SECS : (long)setting.intValue() * 60; + return 1000 * (getForever() ? FOREVER_SECS : longSetting); + } + + /** + * Determines whether the user's session should be invalidated. + * + * @param value the new value for the credential + * + * @return true if the credential is set and has the wrong value. + **/ + protected boolean shouldInvalidateSession(String value) + throws LoginException { + return credentialIsSet() && !credentialHasValue(value); + } +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepagePortalSelectionModel.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepagePortalSelectionModel.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepagePortalSelectionModel.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001 ArsDigita Corporation. All Rights Reserved. + * + * The contents of this file are subject to the ArsDigita Public + * License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of + * the License at http://www.arsdigita.com/ADPL.txt + * + * 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. + * + */ +/** + * replacement for default version in com.arsdigita.aplaws.ui + * In actual fact this is identical, but it is required so that the + * constructor can take our custom version of HomepageWorkspaceSelectionModel + */ +package uk.gov.westsussex.aplaws.ui; + +import com.arsdigita.bebop.AbstractSingleSelectionModel; +import com.arsdigita.london.portal.ui.PortalSelectionModel; +import com.arsdigita.london.portal.WorkspacePage; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.parameters.ParameterModel; +import com.arsdigita.domain.DomainObject; + +public class HomepagePortalSelectionModel extends AbstractSingleSelectionModel + implements PortalSelectionModel { + + private HomepageWorkspaceSelectionModel m_workspace; + private int m_column; + + public HomepagePortalSelectionModel(HomepageWorkspaceSelectionModel workspace, + int column) { + m_workspace = workspace; + m_column = column; + } + + public void onCustomize(PageState state) { + m_workspace.onCustomize(state, m_column); + } + + public void onReset(PageState state) { + m_workspace.onReset(state, m_column); + } + + public HomepageWorkspaceSelectionModel getWorkspaceModel() { + return m_workspace; + } + + public Object getSelectedKey(PageState state) { + return getSelectedPortal(state).getID(); + } + + public void setSelectedKey(PageState state, + Object key) { + throw new UnsupportedOperationException("cannot set key"); + } + + public void setSelectedObject(PageState state, + DomainObject key) { + throw new UnsupportedOperationException("cannot set object"); + } + + public ParameterModel getStateParameter() { + throw new UnsupportedOperationException("not state param"); + } + + + public DomainObject getSelectedObject(PageState state) { + return getSelectedPortal(state); + } + + public WorkspacePage getSelectedPortal(PageState state) { + return m_workspace.getPortal(state, m_column); + } +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspace.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspace.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspace.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2001 ArsDigita Corporation. All Rights Reserved. + * + * The contents of this file are subject to the ArsDigita Public + * License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of + * the License at http://www.arsdigita.com/ADPL.txt + * + * 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 uk.gov.westsussex.aplaws.ui; + +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.Page; +import com.arsdigita.bebop.event.ActionEvent; +import com.arsdigita.bebop.event.ActionListener; +import com.arsdigita.london.portal.ui.PersistentPortal; +import com.arsdigita.london.portal.StatefulPersistentPortal; +import com.arsdigita.london.portal.Workspace; +import com.arsdigita.bebop.PageState; +import com.arsdigita.xml.Element; +import com.arsdigita.london.portal.ui.PortalConstants; +import com.arsdigita.kernel.permissions.PermissionService; +import com.arsdigita.kernel.permissions.PermissionDescriptor; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +import com.arsdigita.kernel.Party; +import com.arsdigita.kernel.Kernel; + + +public class HomepageWorkspace extends SimpleContainer { + + private HomepagePortalSelectionModel m_model; + private ActionLink m_reset; + private ActionLink m_browse; + private ActionLink m_edit; + private StatefulPersistentPortal m_browser; + private PersistentPortal m_editor; + private boolean m_customizable; + private boolean m_readOnly; + private String m_name; + + public HomepageWorkspace() { + super("portal:homepageWorkspace", PortalConstants.PORTAL_XML_NS); + m_customizable = false; + } + + public void setModel(HomepagePortalSelectionModel model) { + m_model = model; + } + + public void setCustomizable(boolean customizable) { + m_customizable = customizable; + } + + public void setReadOnly(boolean readOnly) { + m_readOnly = readOnly; + } + + public void setName(String name) { + m_name = name; + } + + public void addWidgets() { + m_edit = new ActionLink("customize"); + m_browse = new ActionLink("browse"); + m_reset = new ActionLink("reset"); + m_reset.setConfirmation("Are you sure you wish to reset this column? " + + "This will permanently remove all portlets."); + + m_browser = new StatefulPersistentPortal(m_model, + m_name); + m_editor = new PersistentPortal(m_model, + m_name, + PortalConstants.MODE_EDITOR); + + m_edit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PageState state = e.getPageState(); + setDisplayMode(state, false); + + m_model.onCustomize(state); + } + }); + m_browse.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PageState state = e.getPageState(); + setDisplayMode(state, true); + } + }); + m_reset.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PageState state = e.getPageState(); + setDisplayMode(state, true); + + m_model.onReset(state); + } + }); + + add(m_edit); + add(m_browse); + add(m_reset); + add(m_editor); + add(m_browser); + } + + public void setDisplayMode(PageState state, + boolean browse) { + if (m_readOnly) { + return; + } + m_browse.setVisible(state, !browse); + m_reset.setVisible(state, !browse); + m_edit.setVisible(state, browse); + m_browser.setVisible(state, browse); + m_editor.setVisible(state, !browse); + } + + public void register(Page page) { + super.register(page); + + page.setVisibleDefault(m_browse, false); + page.setVisibleDefault(m_reset, false); + page.setVisibleDefault(m_edit, !m_readOnly); + page.setVisibleDefault(m_browser, true); + page.setVisibleDefault(m_editor, false); + } + + public void generateXML(PageState state, + Element parent) { + Party party = Kernel.getContext().getParty(); + Workspace global = m_model.getWorkspaceModel().getGlobalWorkspace(state); + PermissionDescriptor admin = + new PermissionDescriptor(PrivilegeDescriptor.ADMIN, + global, + party); + boolean hasAdmin = PermissionService.checkPermission(admin); + + if (party == null || m_readOnly || + (!hasAdmin && !m_customizable)) { + m_reset.setVisible(state, false); + m_browse.setVisible(state, false); + m_edit.setVisible(state, false); + } + + super.generateXML(state, parent); + } + +} Added: aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspaceSelectionModel.java =================================================================== --- aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspaceSelectionModel.java (rev 0) +++ aplaws/contrib/wsx/ccm-wsx-wsgfl-custom/src/uk/gov/westsussex/aplaws/ui/HomepageWorkspaceSelectionModel.java 2007-09-17 10:00:38 UTC (rev 1635) @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2001 ArsDigita Corporation. All Rights Reserved. + * + * The contents of this file are subject to the ArsDigita Public + * License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of + * the License at http://www.arsdigita.com/ADPL.txt + * + * 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. + * + */ +/** + * Replacement for default version in com.arsdigita.aplaws.ui - simply adds an extra workspace page, + * as we didn't want the whole of the right hand side to disappear as soon as a user customizes it + +//to do - sort this out so it is flexible enough to deal with any number of pages - +//generally straightforward - only problem arises in getPortal - there is currently no +//persistent information to tell us that portal is customizable or not +//could be a bit tricky + +*/ + +package uk.gov.westsussex.aplaws.ui; + +import org.apache.log4j.Logger; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.RequestLocal; +import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.kernel.Kernel; +import com.arsdigita.kernel.Party; +import com.arsdigita.kernel.User; +import com.arsdigita.kernel.permissions.PermissionDescriptor; +import com.arsdigita.kernel.permissions.PermissionService; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +import com.arsdigita.london.portal.Workspace; +import com.arsdigita.london.portal.WorkspacePage; +import com.arsdigita.london.portal.WorkspacePageCollection; +import com.arsdigita.london.subsite.Subsite; +import com.arsdigita.util.Assert; +import com.arsdigita.util.UncheckedWrapperException; + +public class HomepageWorkspaceSelectionModel { + private RequestLocal m_loaded = new RequestLocal(); + private RequestLocal m_global = new RequestLocal(); + // custom Workspace + private RequestLocal m_personal = new RequestLocal(); + // workspacePages + private RequestLocal m_left = new RequestLocal(); + private RequestLocal m_middle = new RequestLocal(); + private RequestLocal m_bottomMiddle = new RequestLocal(); + private RequestLocal m_bottomMiddleCustom = new RequestLocal(); + private RequestLocal m_right = new RequestLocal(); + private RequestLocal m_bottomRight = new RequestLocal(); + private RequestLocal m_bottomRightCustom = new RequestLocal(); + + private static Logger s_log = + Logger.getLogger(HomepageWorkspaceSelectionModel.class.getName()); + + public WorkspacePage getPortal(PageState state, int column) { + if (!Boolean.TRUE.equals(m_loaded.get(state))) { + loadWorkspacePages(state); + } + + if (column == 0) { // Always global portal + return (WorkspacePage) m_left.get(state); + } else if (column == 1) { // Always global portal + return (WorkspacePage) m_middle.get(state); + } else if (column == 2) { // Always global portal + return (WorkspacePage) m_right.get(state); + } else if ( + column == 3) { // Right Hand Personal portal, fallback on global + Party party = (Party) Kernel.getContext().getParty(); + WorkspacePage ri... [truncated message content] |