diff --git a/ccm-cms-types-project/application.xml b/ccm-cms-types-project/application.xml
new file mode 100644
index 000000000..35789a292
--- /dev/null
+++ b/ccm-cms-types-project/application.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content type representing a project.
+
+
\ No newline at end of file
diff --git a/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project.pdl b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project.pdl
new file mode 100644
index 000000000..bfb0875eb
--- /dev/null
+++ b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project.pdl
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2009 Jens Pelzetter, for the Center of Social Politics of the University of Bremen
+//
+// 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
+//
+//
+
+model com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ContentPage;
+import com.arsdigita.cms.DomainObject;
+
+object type Project extends ContentPage {
+ String[0..1] projectname = ct_projects.projectname VARCHAR(512);
+ String[0..1] funding = ct_projects.funding VARCHAR(2048);
+ String[0..1] projectDescription = ct_projects.projectdescription VARCHAR(2048);
+ Project2OrgaUnit[0..n] organizationalUnits = join ct_projects.project_id to ct_project2orgaunits.owner_id;
+ Date[0..1] beginDate = ct_projects.beginDate DATE;
+ Date[0..1] endDate = ct_projects.endDate DATE;
+ //boolean finished = ct_projects.finished BOOLEAN;
+
+ reference key (ct_projects.project_id);
+}
\ No newline at end of file
diff --git a/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2OrgaUnit.pdl b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2OrgaUnit.pdl
new file mode 100644
index 000000000..dad61f72a
--- /dev/null
+++ b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2OrgaUnit.pdl
@@ -0,0 +1,70 @@
+//
+// Copyright (C) 2009 Jens Pelzetter, for the Center of Social Politics of the University of Bremen
+//
+// 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
+//
+//
+
+model com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.kernel.ACSObject;
+
+object type Project2OrgaUnit extends ACSObject {
+ OrganizationalUnit[0..1] targetItem = join ct_project2orgaunits.target_item_id to ct_organizationalunits.organizationalunit_id;
+
+ Integer[0..1] unitOrder = ct_project2orgaunits.unit_order INTEGER;
+
+ reference key(ct_project2orgaunits.project2orgaunit_id);
+ aggressive load(project.id);
+}
+
+association {
+ composite Project[0..1] project = join ct_project2orgaunits.project_id to ct_projects.project_id;
+ composite Project2OrgaUnit[0..n] units = join ct_projects.project_id to ct_project2orgaunits.project_id;
+}
+
+query getReferingProjects {
+ BigDecimal id;
+
+ do {
+ select u.organizationalunit_id from project2orgaunits u where u.target_item_id = :itemID
+ } map {
+ id = u.project2orgaunit_id;
+ }
+}
+
+data operation swapProject2OrgaUnitWithNextInGroup {
+ do {
+ update ct_project2orgaunits
+ set unit_order = CASE WHEN (unit_order = :unitOrder) THEN
+ (:nextUnitOrder)
+ ELSE
+ (:unitOrder)
+ END
+ where (unit_order = :unitOrder or unit_order = :nextUnitOrder)
+ and project_id = :projectID
+ }
+}
+
+query allUnitsOrderForProject {
+ Integer unitOrder;
+
+ do {
+ select u.unit_order from ct_project2orgaunits u where u.project_id = :projectID
+ } map {
+ unitOrder = u.unit_order;
+ }
+}
diff --git a/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2Person.pdl b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2Person.pdl
new file mode 100644
index 000000000..3950f88b2
--- /dev/null
+++ b/ccm-cms-types-project/pdl/com/arsdigita/cms/content-types/Project2Person.pdl
@@ -0,0 +1,69 @@
+//
+// Copyright (C) 2009 Center for Social Policy Reseearch, University of Bremen
+//
+// 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
+
+model com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.kernel.ACSObject;
+
+object type Project2Person extends ACSObject {
+ String[0..1] task = ct_project2persons.task VARCHAR(150);
+ Person[0..1] targetItem = join ct_project2persons.target_item_id to ct_persons.person_id;
+
+ Integer[0..1] personOrder = ct_project2persons.person_order INTEGER;
+
+ reference key(ct_project2persons.project2person_id);
+ aggressive load(project.id);
+}
+
+association {
+ composite Project[0..1] project = join ct_project2persons.project_id to ct_projects.project_id;
+ composite Project2Person[0..n] project2Person = join ct_projects.project_id to ct_project2persons.project_id;
+}
+
+query getReferingProject2Persons {
+ BigDecimal id;
+
+ do {
+ select p.project2person_id from ct_project2persons p where p.target_item_id = :itemID
+ } map {
+ id = p.project2person_id;
+ }
+}
+
+data operation swapProject2PersonWithNextInGroup {
+ do {
+ update ct_project2persons
+ set person_order = CASE WHEN (person_order = :personOrder) THEN
+ (:nextPersonOrder)
+ ELSE
+ (:personOrder)
+ END
+ where (person_order = :personOrder or personOrder = :nextPersonOrder)
+ and project_id = :projectID;
+ }
+}
+
+query allRoleOrderForProject2Person {
+ Integer personOrder;
+
+ do {
+ select p.person_order from ct_project2persons p where p.project_id = :projectID
+ } map {
+ personOrder = p.person_order;
+ }
+}
diff --git a/ccm-cms-types-project/src/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Project.xml b/ccm-cms-types-project/src/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Project.xml
new file mode 100644
index 000000000..a2b4883a4
--- /dev/null
+++ b/ccm-cms-types-project/src/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Project.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ccm-cms-types-project/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contenttypes/Project.xml b/ccm-cms-types-project/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contenttypes/Project.xml
new file mode 100644
index 000000000..de41cb2c4
--- /dev/null
+++ b/ccm-cms-types-project/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contenttypes/Project.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ccm-cms-types-project/src/ccm-cms-types-project.config b/ccm-cms-types-project/src/ccm-cms-types-project.config
new file mode 100644
index 000000000..b6865e594
--- /dev/null
+++ b/ccm-cms-types-project/src/ccm-cms-types-project.config
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/ccm-cms-types-project/src/ccm-cms-types-project.load b/ccm-cms-types-project/src/ccm-cms-types-project.load
new file mode 100644
index 000000000..7a768ed04
--- /dev/null
+++ b/ccm-cms-types-project/src/ccm-cms-types-project.load
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project.java
new file mode 100644
index 000000000..bfbd7bddb
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 Jens Pelzetter, for the Center for Social Policy Research of the University of Bremen
+ *
+ * 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.cms.contenttypes;
+
+import com.arsdigita.cms.ContentPage;
+import com.arsdigita.domain.DataObjectNotFoundException;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.persistence.OID;
+import java.math.BigDecimal;
+import java.util.Date;
+import org.apache.log4j.Logger;
+
+/**
+ * Contenttype which represents a (scientific) project.
+ *
+ * @author Jens Pelzetter
+ */
+public class Project extends ContentPage {
+
+ public static final String PROJECTNAME = "projectname";
+ public static final String FUNDING = "funding";
+ public static final String PROJECT_DESCRIPTION = "projectDescription";
+ public static final String BEGINDATE = "beginDate";
+ public static final String ENDDATE = "endDate";
+ //public static final String FINISHED = "finished";
+ public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contenttypes.Project";
+ private static final Logger s_log = Logger.getLogger(Project.class);
+
+ public Project() {
+ this(BASE_DATA_OBJECT_TYPE);
+ }
+
+ public Project(BigDecimal id) throws DataObjectNotFoundException {
+ this(new OID(BASE_DATA_OBJECT_TYPE, id));
+ }
+
+ public Project(OID oid) throws DataObjectNotFoundException {
+ super(oid);
+ }
+
+ public Project(DataObject obj) {
+ super(obj);
+ }
+
+ public Project(String type) {
+ super(type);
+ }
+
+ /* accessors ********************************/
+ public String getProjectName() {
+ return (String) get(PROJECTNAME);
+ }
+
+ public void setProjectName(String projectName) {
+ set(PROJECTNAME, projectName);
+ }
+
+ public String getFunding() {
+ return (String) get(FUNDING);
+ }
+
+ public void setFunding(String funding) {
+ set(FUNDING, funding);
+ }
+
+ public String getProjectDescription() {
+ return (String) get(PROJECT_DESCRIPTION);
+ }
+
+ public void setProjectDescription(String projectDescription) {
+ set(PROJECT_DESCRIPTION, projectDescription);
+ }
+
+ public Date getBegin() {
+ return (Date) get(BEGINDATE);
+ }
+
+ public void setBegin(Date begin) {
+ set(BEGINDATE, begin);
+ }
+
+ public Date getEnd() {
+ return (Date) get(ENDDATE);
+ }
+
+ public void setEnd(Date end) {
+ set(ENDDATE, end);
+ }
+
+ /*public Boolean getFinished() {
+ return (Boolean)get(FINISHED);
+ }
+
+ public void setFinished(Boolean finished) {
+ set(FINISHED, finished);
+ }*/
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2OrgaUnit.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2OrgaUnit.java
new file mode 100644
index 000000000..a433be547
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2OrgaUnit.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2009 Jens Pelzetter, for the Center for Social Policy Research of the University of Bremen
+ *
+ * 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.cms.contenttypes;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.dispatcher.ItemResolver;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.kernel.ACSObject;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.persistence.DataOperation;
+import com.arsdigita.persistence.DataQuery;
+import com.arsdigita.persistence.Filter;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.persistence.Session;
+import com.arsdigita.persistence.SessionManager;
+import com.arsdigita.util.Assert;
+import com.arsdigita.web.URL;
+import java.math.BigDecimal;
+import org.apache.log4j.Logger;
+
+/**
+ * Represents the relationship between a organizational unit and a project.
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnit extends ACSObject {
+
+ private static final Logger s_log = Logger.getLogger(Project2OrgaUnit.class);
+
+ public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contenttypes.Project2OrgaUnit";
+
+ public static final String TARGET_ITEM = "targetItem";
+ public static final String PROJECT = "project";
+ public static final String UNIT_ORDER = "unitOrder";
+
+ public Project2OrgaUnit() {
+ this(BASE_DATA_OBJECT_TYPE);
+ }
+
+ public Project2OrgaUnit(BigDecimal id) {
+ this(new OID(BASE_DATA_OBJECT_TYPE, id));
+ }
+
+ public Project2OrgaUnit(OID oid) {
+ super(oid);
+ }
+
+ public Project2OrgaUnit(DataObject obj) {
+ super(obj);
+ }
+
+ public Project2OrgaUnit(String type) {
+ super(type);
+ }
+
+ public Project getProject() {
+ DataObject obj = (DataObject) get(PROJECT);
+ if (obj == null) {
+ return null;
+ } else {
+ return (Project) DomainObjectFactory.newInstance(obj);
+ }
+ }
+
+ public void setProject(Project project) {
+ Assert.exists(project, Project.class);
+ s_log.debug(String.format("Setting project to %s", project.getProjectName()));
+ setAssociation(PROJECT, project);
+ }
+
+ public OrganizationalUnit getTargetItem() {
+ DataObject object = (DataObject) get(TARGET_ITEM);
+ if (object == null) {
+ return null;
+ } else {
+ return (OrganizationalUnit) DomainObjectFactory.newInstance(object);
+ }
+ }
+
+ public void setTargetItem(OrganizationalUnit orgaUnit) {
+ Assert.exists(orgaUnit, OrganizationalUnit.class);
+ setAssociation(TARGET_ITEM, orgaUnit);
+ }
+
+ public Integer getOrder() {
+ return (Integer) get(UNIT_ORDER);
+ }
+
+ public void setOrder(Integer order) {
+ Assert.exists(order);
+ set(UNIT_ORDER, order);
+ }
+
+ public String getURI(PageState state) {
+ OrganizationalUnit orgaUnit = getTargetItem();
+
+ if (orgaUnit == null) {
+ s_log.error(getOID() + "is a link between a project and a organizational unit, but the associated organizational unit is null");
+ return "";
+ }
+
+ ContentSection section = orgaUnit.getContentSection();
+ ItemResolver resolver = section.getItemResolver();
+ String url = resolver.generateItemURL(state, orgaUnit, section, orgaUnit.getVersion());
+
+ return URL.there(state.getRequest(), url).toString();
+ }
+
+ public static DataCollection getReferingProjects(OrganizationalUnit orgaUnit) {
+ Session session = SessionManager.getSession();
+ DataCollection projects = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ Filter filter = projects.addInSubqueryFilter("id", "com.arsdigita.cmscontenttypes.getReferingProjects");
+ filter.set("itemID", orgaUnit.getID());
+
+ return projects;
+ }
+
+ public static DataCollection getUnits(Project project) {
+ Session session = SessionManager.getSession();
+ DataCollection units = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ units.addEqualsFilter(PROJECT + ".id", project.getID());
+ units.addOrder(UNIT_ORDER);
+
+ return units;
+ }
+
+ public void swapWithNext() {
+ swapWithNext("com.arsdigita.cms.contenttypes.allUnitsOrderForProject", "com.arsdigita.cms.contenttypes.swapProject2OrgaUnitWithNextInGroup");
+ }
+
+ public void swapWithPrevious() {
+ swapWithPrevious("com.arsdigita.cms.contenttypes.allUnitsOrderForProject", "com.arsdigita.cms.contenttypes.swapProject2OrgaUnitWithNextInGroup");
+ }
+
+ public void swapWithNext(String queryName, String operationName) {
+ swapKeys(true, queryName, operationName);
+ }
+
+ public void swapWithPrevious(String queryName, String operationName) {
+ swapKeys(false, queryName, operationName);
+ }
+
+ protected DataQuery getSwapQuery(String queryName) {
+ DataQuery query = SessionManager.getSession().retrieveQuery(queryName);
+ query.setParameter("projectID", getProject().getID());
+ return query;
+ }
+
+ protected DataOperation getSwapOperation(String operationName) {
+ DataOperation operation = SessionManager.getSession().retrieveDataOperation(operationName);
+ operation.setParameter("projectID", getProject().getID());
+ return operation;
+ }
+
+ protected void swapKeys(boolean swapNext, String queryName, String operationName) {
+
+ String methodName = null;
+ if (swapNext) {
+ methodName = "swapWithNext";
+ } else {
+ methodName = "swapWithPrevious";
+ }
+
+ Assert.isTrue(!isNew(), methodName + " cannon be called on an object that is new");
+
+ Integer currentKey = (Integer) get(UNIT_ORDER);
+
+ if (currentKey == null) {
+ alphabetize();
+ return;
+ }
+
+ Assert.isTrue(currentKey != null, methodName + "cannot be called on a object htat is not currently in the list");
+
+ int key = currentKey.intValue();
+ s_log.debug("current key: " + currentKey);
+ s_log.debug("key = " + key);
+
+ DataQuery query = getSwapQuery(queryName);
+
+ int otherKey;
+ if(swapNext) {
+ otherKey = key + 1;
+ query.addOrder("unitOrder ASC");
+ query.addFilter(query.getFilterFactory().greaterThan("unitOrder", currentKey, true));
+ } else {
+ otherKey = key - 1;
+ query.addOrder("unitOrder DESC");
+ query.addFilter(query.getFilterFactory().lessThan("unitOrder", currentKey, true));
+ }
+
+ if(query.next()) {
+ otherKey = ((Integer) query.get("unitOrder")).intValue();
+ query.close();
+ }
+
+ s_log.debug("otherKey = " + otherKey);
+ DataOperation operation = getSwapOperation(operationName);
+ operation.setParameter("unitOrder", new Integer(key));
+ operation.setParameter("nextUnitOrder", new Integer(otherKey));
+ operation.execute();
+ }
+
+ public void alphabetize() {
+ Session session = SessionManager.getSession();
+ DataCollection projects = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ projects.addEqualsFilter(PROJECT + ".id", getProject().getID());
+ int sortKey = 0;
+ while(projects.next()) {
+ sortKey++;
+ Project2OrgaUnit p2ou = new Project2OrgaUnit(projects.getDataObject());
+ p2ou.setOrder(sortKey);
+ p2ou.save();
+ }
+ }
+
+ public int maxOrder() {
+ Project project = getProject();
+ if (project == null) {
+ return 0;
+ }
+
+ int returnOrder = 0;
+ DataQuery query = SessionManager.getSession().retrieveQuery("com.arsdigita.cms.contenttypes.allUnitsOrderForProject");
+ query.setParameter("projectID", getProject().getID());
+ query.addOrder("unitOrder DESC");
+ if(query.next()) {
+ Integer unitOrder = ((Integer) query.get("unitOrder"));
+ query.close();
+ if(unitOrder != null) {
+ returnOrder = unitOrder.intValue();
+ }
+ }
+
+ return returnOrder;
+ }
+
+ @Override
+ public void beforeSave() {
+ super.beforeSave();
+ if (getOrder() == null) {
+ setOrder(maxOrder() + 1);
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2Person.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2Person.java
new file mode 100644
index 000000000..f97d2d30c
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/Project2Person.java
@@ -0,0 +1,247 @@
+package com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.dispatcher.ItemResolver;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.kernel.ACSObject;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.persistence.DataOperation;
+import com.arsdigita.persistence.DataQuery;
+import com.arsdigita.persistence.Filter;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.persistence.Session;
+import com.arsdigita.persistence.SessionManager;
+import com.arsdigita.util.Assert;
+import com.arsdigita.web.URL;
+import java.math.BigDecimal;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2Person extends ACSObject {
+
+ private final static Logger s_log = Logger.getLogger(Project2Person.class);
+ public final static String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contenttypes.Project2Person";
+ public final static String TASK = "task";
+ public final static String TARGET_ITEM = "targetItem";
+ public static final String PROJECT = "project";
+ public final static String ROLE_ORDER = "personOrder";
+ public final static String PROJECT2PERSON = "project2Person";
+
+ public Project2Person() {
+ super(BASE_DATA_OBJECT_TYPE);
+ }
+
+ public Project2Person(DataObject obj) {
+ super(obj);
+ }
+
+ public Project2Person(BigDecimal id) {
+ this(new OID(BASE_DATA_OBJECT_TYPE, id));
+ }
+
+ public Project2Person(OID oid) {
+ super(oid);
+ }
+
+ public Project2Person(String type) {
+ super(type);
+ }
+
+ public String getTask() {
+ return (String) get(TASK);
+ }
+
+ public void setTask(String task) {
+ set(TASK, task);
+ }
+
+ public Project getProject() {
+ DataObject obj = (DataObject) get(PROJECT);
+ if (obj == null) {
+ return null;
+ } else {
+ return (Project) DomainObjectFactory.newInstance(obj);
+ }
+ }
+
+ public void setProject(Project project) {
+ Assert.exists(project, Project.class);
+ setAssociation(PROJECT, project);
+ }
+
+ public Person getTargetItem() {
+ DataObject obj = (DataObject) get(TARGET_ITEM);
+ if (obj == null) {
+ return null;
+ } else {
+ return (Person) DomainObjectFactory.newInstance(obj);
+ }
+ }
+
+ public void setTargetItem(Person person) {
+ Assert.exists(person, Person.class);
+ setAssociation(TARGET_ITEM, person);
+ }
+
+ public Integer getOrder() {
+ return (Integer) get(ROLE_ORDER);
+ }
+
+ public void setOrder(Integer order) {
+ Assert.exists(order);
+ set(ROLE_ORDER, order);
+ }
+
+
+ public String getURI(PageState state) {
+ Person person = this.getTargetItem();
+
+ if (person == null) {
+ s_log.error(getOID() + " is a link between a Project and a Person, but the associated Person is null");
+ return "";
+ }
+
+ ContentSection section = person.getContentSection();
+ ItemResolver resolver = section.getItemResolver();
+ String url = resolver.generateItemURL(state, person, section, person.getVersion());
+
+ return URL.there(state.getRequest(), url).toString();
+ }
+
+ public static DataCollection getReferingProject2Persons(Person person) {
+ Session session = SessionManager.getSession();
+ DataCollection project2Persons = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ Filter filter = project2Persons.addInSubqueryFilter("id", "com.arsdigita.cms.contenttypes.getReferingProject2Persons");
+ filter.set("itemID", person.getID());
+
+ return project2Persons;
+ }
+
+ public static DataCollection getProject2Persons(Project project) {
+ Session session = SessionManager.getSession();
+ DataCollection dc = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ dc.addEqualsFilter(PROJECT + ".id", project.getID());
+ return dc;
+ }
+
+ public void swapWithNext() {
+ swapWithNext("com.arsdigita.cms.contenttypes.allPersonsOrderForProject", "com.arsdigita.cms.contenttypes.swapProject2OrgaPersonWithNextInGroup");
+ }
+
+ public void swapWithPrevious() {
+ swapWithPrevious("com.arsdigita.cms.contenttypes.allPersonsOrderForProject", "com.arsdigita.cms.contenttypes.swapProject2OrgaPersonWithNextInGroup");
+ }
+
+ public void swapWithNext(String queryName, String operationName) {
+ swapKeys(true, queryName, operationName);
+ }
+
+ public void swapWithPrevious(String queryName, String operationName) {
+ swapKeys(false, queryName, operationName);
+ }
+
+ protected DataQuery getSwapQuery(String queryName) {
+ DataQuery query = SessionManager.getSession().retrieveQuery(queryName);
+ query.setParameter("projectID", getProject().getID());
+ return query;
+ }
+
+ protected DataOperation getSwapOperation(String operationName) {
+ DataOperation operation = SessionManager.getSession().retrieveDataOperation(operationName);
+ operation.setParameter("projectID", getProject().getID());
+ return operation;
+ }
+
+ protected void swapKeys(boolean swapNext, String queryName, String operationName) {
+
+ String methodName = null;
+ if (swapNext) {
+ methodName = "swapWithNext";
+ } else {
+ methodName = "swapWithPrevious";
+ }
+
+ Assert.isTrue(!isNew(), methodName + " cannon be called on an object that is new");
+
+ Integer currentKey = (Integer) get(ROLE_ORDER);
+
+ if (currentKey == null) {
+ alphabetize();
+ return;
+ }
+
+ Assert.isTrue(currentKey != null, methodName + "cannot be called on a object htat is not currently in the list");
+
+ int key = currentKey.intValue();
+
+ DataQuery query = getSwapQuery(queryName);
+
+ int otherKey;
+ if (swapNext) {
+ otherKey = key + 1;
+ query.addOrder("personOrder ASC");
+ query.addFilter(query.getFilterFactory().greaterThan("personOrder", currentKey, true));
+ } else {
+ otherKey = key - 1;
+ query.addOrder("personOrder DESC");
+ query.addFilter(query.getFilterFactory().lessThan("personOrder", currentKey, true));
+ }
+
+ if (query.next()) {
+ otherKey = ((Integer) query.get("personOrder")).intValue();
+ query.close();
+ }
+
+ DataOperation operation = getSwapOperation(operationName);
+ operation.setParameter("personOrder", new Integer(key));
+ operation.setParameter("nextPersonOrder", new Integer(otherKey));
+ operation.execute();
+ }
+
+ public void alphabetize() {
+ Session session = SessionManager.getSession();
+ DataCollection projects = session.retrieve(BASE_DATA_OBJECT_TYPE);
+ projects.addEqualsFilter(PROJECT + ".id", getProject().getID());
+ int sortKey = 0;
+ while (projects.next()) {
+ sortKey++;
+ Project2Person p2ou = new Project2Person(projects.getDataObject());
+ p2ou.setOrder(sortKey);
+ p2ou.save();
+ }
+ }
+
+ public int maxOrder() {
+ Project project = getProject();
+ if (project == null) {
+ return 0;
+ }
+
+ int returnOrder = 0;
+ DataQuery query = SessionManager.getSession().retrieveQuery("com.arsdigita.cms.contenttypes.allRoleOrderForProject2Person");
+ query.setParameter("projectID", getProject().getID());
+ query.addOrder("personOrder DESC");
+ if (query.next()) {
+ Integer personOrder = ((Integer) query.get("personOrder"));
+ query.close();
+ if (personOrder != null) {
+ returnOrder = personOrder.intValue();
+ }
+ }
+
+ return returnOrder;
+ }
+
+ @Override
+ public void beforeSave() {
+ super.beforeSave();
+ if (getOrder() == null) {
+ setOrder(maxOrder() + 1);
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectGlobalizationUtil.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectGlobalizationUtil.java
new file mode 100644
index 000000000..f195d3b8f
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectGlobalizationUtil.java
@@ -0,0 +1,29 @@
+package com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.globalization.GlobalizedMessage;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProjectGlobalizationUtil {
+
+ final public static String BUNDLE_NAME =
+ "com.arsdigita.cms.contenttypes.ProjectResourceBundle";
+
+ /**
+ * This returns a globalized message using the type specific bundle,
+ * BUNDLE_NAME
+ */
+ public static GlobalizedMessage globalize(String key) {
+ return new GlobalizedMessage(key, BUNDLE_NAME);
+ }
+
+ /**
+ * This returns a globalized message using the type specific bundle,
+ * BUNDLE_NAME
+ */
+ public static GlobalizedMessage globalize(String key, Object[] args) {
+ return new GlobalizedMessage(key, BUNDLE_NAME, args);
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectInitializer.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectInitializer.java
new file mode 100644
index 000000000..145ea9555
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectInitializer.java
@@ -0,0 +1,27 @@
+package com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.runtime.LegacyInitEvent;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProjectInitializer extends ContentTypeInitializer {
+
+ private final static Logger s_log = Logger.getLogger(ProjectInitializer.class);
+
+ public ProjectInitializer() {
+ super("ccm-cms-types-project.pdl.mf", Project.BASE_DATA_OBJECT_TYPE);
+ }
+
+ @Override
+ public String[] getStylesheets() {
+ return new String[]{"/static/content-types/com/arsdigita/cms/contenttypes/Project.xsl"};
+ }
+
+ @Override
+ public String getTraversalXML() {
+ return "/WEB-INF/traversal-adapters/com/arsdigita/cms/contenttypes/Project.xml";
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectLoader.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectLoader.java
new file mode 100644
index 000000000..673206888
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectLoader.java
@@ -0,0 +1,22 @@
+package com.arsdigita.cms.contenttypes;
+
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProjectLoader extends AbstractContentTypeLoader {
+
+
+ private final static Logger s_log = Logger.getLogger(ProjectLoader.class);
+ private final static String[] TYPES = {"/WEB-INF/content-types/com/arsdigita/cms/contenttypes/Project.xml"};
+
+ public String[] getTypes() {
+ return TYPES;
+ }
+
+ public ProjectLoader() {
+ super();
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResourceBundle.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResourceBundle.java
new file mode 100644
index 000000000..6c6ca369d
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResourceBundle.java
@@ -0,0 +1,22 @@
+package com.arsdigita.cms.contenttypes;
+
+import com.arsdigita.cms.CMSGlobalized;
+import com.arsdigita.globalization.ChainedResourceBundle;
+import java.util.PropertyResourceBundle;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@SuppressWarnings("unchecked")
+public class ProjectResourceBundle extends ChainedResourceBundle implements CMSGlobalized {
+
+ public final static String PROJECT_BUNDLE_NAME =
+ "com.arsdigita.cms.contenttypes.ProjectResources";
+
+ public ProjectResourceBundle() {
+ super();
+ addBundle((PropertyResourceBundle)getBundle(PROJECT_BUNDLE_NAME));
+ addBundle((PropertyResourceBundle)getBundle(BUNDLE_NAME));
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResources.properties b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResources.properties
new file mode 100644
index 000000000..a43a4153c
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ProjectResources.properties
@@ -0,0 +1,7 @@
+#project.authoring.basic_properties.description = Description
+#project.authoring.project2orgaunit.description = Description
+#project.authoring.project2person.description = Description
+
+project.authoring.project2orgaunit.title = Organizational units involved
+project.authoring.project2person.title = Persons involved
+project.authoring.basic_properties.title = Basic properties
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertiesStep.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertiesStep.java
new file mode 100644
index 000000000..b5b152fd6
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertiesStep.java
@@ -0,0 +1,76 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.Form;
+import com.arsdigita.bebop.FormSection;
+import com.arsdigita.bebop.Page;
+import com.arsdigita.bebop.SimpleContainer;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.ui.ResettableContainer;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedContainer;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnitPropertiesStep extends ResettableContainer {
+
+ private AuthoringKitWizard m_parent;
+ private ItemSelectionModel m_itemModel;
+ private BigDecimalParameter m_p2ouParam =
+ new BigDecimalParameter("project2orgaunit");
+ private Project2OrgaUnitSelectionModel m_p2ouModel =
+ new Project2OrgaUnitSelectionModel(m_p2ouParam);
+
+ public Project2OrgaUnitPropertiesStep(
+ ItemSelectionModel itemModel,
+ AuthoringKitWizard parent) {
+ m_itemModel = itemModel;
+ m_parent = parent;
+ setProject2OrgaUnitSelectionModel();
+ add(getDisplayComponent());
+
+ Form form = new Form("project2OrgaUnitEditForm");
+ form.add(getEditSheet());
+
+ WorkflowLockedContainer edit = new WorkflowLockedContainer(itemModel);
+ edit.add(form);
+ add(edit);
+ }
+
+ protected void setProject2OrgaUnitSelectionModel() {
+ setProject2OrgaUnitSelectionModel(
+ new Project2OrgaUnitSelectionModel(m_p2ouParam));
+ }
+
+ protected void setProject2OrgaUnitSelectionModel(
+ Project2OrgaUnitSelectionModel model) {
+ m_p2ouModel = model;
+ }
+
+ protected Project2OrgaUnitSelectionModel getProject2OrgaUnitSelelectioModel() {
+ return m_p2ouModel;
+ }
+
+ protected BigDecimalParameter getP2OUParameter() {
+ return m_p2ouParam;
+ }
+
+ public Component getDisplayComponent() {
+ SimpleContainer container = new SimpleContainer();
+ container.add(new Project2OrgaUnitTable(m_itemModel, m_p2ouModel));
+ return container;
+ }
+
+ public FormSection getEditSheet() {
+ return new Project2OrgaUnitPropertyForm(m_itemModel, m_p2ouModel);
+ }
+
+ @Override
+ public void register(Page p) {
+ super.register(p);
+ p.addComponentStateParam(this, m_p2ouParam);
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertyForm.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertyForm.java
new file mode 100644
index 000000000..76d95e0d5
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitPropertyForm.java
@@ -0,0 +1,189 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.ColumnPanel;
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.FormSection;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.SaveCancelSection;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.event.FormSubmissionListener;
+import com.arsdigita.bebop.event.FormValidationListener;
+import com.arsdigita.bebop.event.PrintEvent;
+import com.arsdigita.bebop.event.PrintListener;
+import com.arsdigita.bebop.form.Submit;
+import com.arsdigita.cms.ContentType;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.OrganizationalUnit;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.Project2OrgaUnit;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.ui.ItemSearchWidget;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.UncheckedWrapperException;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnitPropertyForm
+ extends FormSection
+ implements FormInitListener,
+ FormProcessListener,
+ FormValidationListener,
+ FormSubmissionListener {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2OrgaUnitPropertyForm.class);
+ private ItemSelectionModel m_itemModel;
+ private Project2OrgaUnitSelectionModel m_p2ouModel;
+ private ItemSearchWidget m_itemSearch;
+ private SaveCancelSection m_saveCancelSection;
+ private final String ITEM_SEARCH = "project2OrgaUnit";
+
+ public Project2OrgaUnitPropertyForm(
+ ItemSelectionModel itemModel,
+ Project2OrgaUnitSelectionModel p2ouModel) {
+ super(new ColumnPanel(2));
+ m_itemModel = itemModel;
+ m_p2ouModel = p2ouModel;
+
+ addWidgets();
+ addSaveCancelSection();
+
+ addInitListener(this);
+ addValidationListener(this);
+ addProcessListener(this);
+ addSubmissionListener(this);
+ }
+
+ protected void addWidgets() {
+ add(new Label(ProjectGlobalizationUtil.globalize(
+ "cms.contenttypes.ui.project.orgaunit")));
+ m_itemSearch = new ItemSearchWidget(ITEM_SEARCH,
+ ContentType.findByAssociatedObjectType(
+ "com.arsdigita.cms.contenttypes.OrganizationalUnit"));
+ add(m_itemSearch);
+ }
+
+ public void addSaveCancelSection() {
+ m_saveCancelSection = new SaveCancelSection();
+ try {
+ m_saveCancelSection.getCancelButton().addPrintListener(new PrintListener() {
+
+ public void prepare(PrintEvent e) {
+ Submit target = (Submit) e.getTarget();
+ if (m_p2ouModel.isSelected(e.getPageState())) {
+ target.setButtonLabel("Cancel");
+ } else {
+ target.setButtonLabel("Reset");
+ }
+ }
+ });
+
+ m_saveCancelSection.getSaveButton().addPrintListener(new PrintListener() {
+
+ public void prepare(PrintEvent e) {
+ Submit target = (Submit) e.getTarget();
+ if (m_p2ouModel.isSelected(e.getPageState())) {
+ target.setButtonLabel("Save");
+ } else {
+ target.setButtonLabel("Create");
+ }
+ }
+ });
+ } catch (Exception ex) {
+ throw new UncheckedWrapperException("this cannot happen", ex);
+ }
+ add(m_saveCancelSection, ColumnPanel.FULL_WIDTH);
+ }
+
+ public SaveCancelSection getSaveCancelSection() {
+ return m_saveCancelSection;
+ }
+
+ protected Project2OrgaUnitSelectionModel getP2OUSelectionModel() {
+ return m_p2ouModel;
+ }
+
+ protected Project getProject(PageState s) {
+ return (Project) m_itemModel.getSelectedItem(s);
+ }
+
+ protected Project2OrgaUnit createProject2OrgaUnit(PageState s) {
+ Project project = getProject(s);
+ Assert.exists(project);
+ Project2OrgaUnit p2ou = new Project2OrgaUnit();
+ p2ou.setProject(project);
+ return p2ou;
+ }
+
+ protected void setProject2OrgaUnitProperties(
+ Project2OrgaUnit p2ou,
+ FormSectionEvent e) {
+ PageState state = e.getPageState();
+ FormData data = e.getFormData();
+
+ p2ou.setTargetItem((OrganizationalUnit) data.get(ITEM_SEARCH));
+
+ p2ou.save();
+ }
+
+ public void init(FormSectionEvent e) throws FormProcessException {
+ FormData data = e.getFormData();
+ PageState state = e.getPageState();
+
+ setVisible(state, true);
+
+ Project2OrgaUnit p2ou;
+ if (m_p2ouModel.isSelected(state)) {
+ p2ou = m_p2ouModel.getSelectedP2OU(state);
+ try {
+ data.put(ITEM_SEARCH, p2ou.getTargetItem());
+ } catch (IllegalStateException ex) {
+ throw ex;
+ }
+ } else {
+ data.put(ITEM_SEARCH, null);
+ }
+ }
+
+ public void process(FormSectionEvent e) throws FormProcessException {
+ PageState state = e.getPageState();
+ Project2OrgaUnit p2ou;
+
+ if (this.getSaveCancelSection().getCancelButton().isSelected(state)) {
+ this.m_p2ouModel.clearSelection(state);
+ } else {
+ if (this.m_p2ouModel.isSelected(state)) {
+ p2ou = m_p2ouModel.getSelectedP2OU(state);
+ } else {
+ p2ou = createProject2OrgaUnit(state);
+ }
+ setProject2OrgaUnitProperties(p2ou, e);
+ }
+
+ m_p2ouModel.clearSelection(state);
+ init(e);
+ }
+
+ public void validate(FormSectionEvent e) throws FormProcessException {
+ if (e.getFormData().get(ITEM_SEARCH) == null) {
+ throw new FormProcessException(
+ "OrganiztionalUnit selection is required");
+ }
+ }
+
+ public void submitted(FormSectionEvent e) throws FormProcessException {
+ if (this.m_saveCancelSection.getCancelButton().isSelected(
+ e.getPageState())) {
+ m_p2ouModel.clearSelection(e.getPageState());
+ init(e);
+ throw new FormProcessException("cancelled");
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitSelectionModel.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitSelectionModel.java
new file mode 100644
index 000000000..50c8320c7
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitSelectionModel.java
@@ -0,0 +1,31 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.cms.contenttypes.Project2OrgaUnit;
+import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnitSelectionModel extends ACSObjectSelectionModel {
+
+ public Project2OrgaUnitSelectionModel(BigDecimalParameter param) {
+ super(Project2OrgaUnit.class.getName(),
+ Project2OrgaUnit.BASE_DATA_OBJECT_TYPE,
+ param);
+ }
+
+ public Project2OrgaUnitSelectionModel(
+ String itemClass,
+ String objectType,
+ BigDecimalParameter param) {
+ super(itemClass, objectType, param);
+ }
+
+ public Project2OrgaUnit getSelectedP2OU(PageState s) {
+ return (Project2OrgaUnit) getSelectedObject(s);
+ }
+
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTable.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTable.java
new file mode 100644
index 000000000..1174a244a
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTable.java
@@ -0,0 +1,220 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+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.table.TableCellRenderer;
+import com.arsdigita.bebop.table.TableColumn;
+import com.arsdigita.bebop.table.TableColumnModel;
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.SecurityManager;
+import com.arsdigita.cms.contenttypes.Project2OrgaUnit;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.dispatcher.Utilities;
+import com.arsdigita.domain.DataObjectNotFoundException;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.UncheckedWrapperException;
+import java.math.BigDecimal;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnitTable extends Table {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2OrgaUnitTable.class);
+ private Project2OrgaUnitSelectionModel m_p2ouModel;
+ private ItemSelectionModel m_itemModel;
+ private TableColumn m_orgaUnitCol;
+ private TableColumn m_moveUpCol;
+ private TableColumn m_moveDownCol;
+ private TableColumn m_editCol;
+ private TableColumn m_delCol;
+ private RequestLocal m_size;
+ private RequestLocal m_editor;
+ protected final static String EDIT_EVENT = "Edit";
+ protected final static String DELETE_EVENT = "Delete";
+ protected final static String UP_EVENT = "up";
+ protected final static String DOWN_EVENT = "down";
+
+ public Project2OrgaUnitTable(
+ ItemSelectionModel itemModel,
+ Project2OrgaUnitSelectionModel p2ouModel) {
+ super();
+ m_itemModel = itemModel;
+ m_p2ouModel = p2ouModel;
+ addColumns();
+
+ m_size = new RequestLocal();
+ m_editor = new RequestLocal() {
+
+ @Override
+ public Object initialValue(PageState s) {
+ SecurityManager sm = Utilities.getSecurityManager(s);
+ ContentItem item = m_itemModel.getSelectedItem(s);
+ Boolean val = new Boolean(sm.canAccess(s.getRequest(), SecurityManager.EDIT_ITEM, item));
+ return val;
+ }
+ };
+
+ Label empty = new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.noOrgaUnitsAssociated"));
+ setEmptyView(empty);
+ addTableActionListener(new Project2OrgaUnitTableActionListener());
+ setRowSelectionModel(p2ouModel);
+ setDefaultCellRenderer(new Project2OrgaUnitTableRenderer());
+ setModelBuilder(new Project2OrgaUnitTableModelBuilder(itemModel));
+ }
+
+ /**
+ * Adds the columns of the table.
+ */
+ public void addColumns() {
+ TableColumnModel model = getColumnModel();
+
+ m_orgaUnitCol = new TableColumn(0,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.orgaunit").localize());
+ m_editCol = new TableColumn(1,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.edit").localize());
+ m_delCol = new TableColumn(2,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project_del").localize());
+ m_moveUpCol = new TableColumn(3, "");
+ m_moveDownCol = new TableColumn(4, "");
+
+ model.add(m_orgaUnitCol);
+ model.add(m_editCol);
+ model.add(m_delCol);
+ model.add(m_moveUpCol);
+ model.add(m_moveDownCol);
+ setColumnModel(model);
+ }
+
+ private class Project2OrgaUnitTableRenderer implements TableCellRenderer {
+
+ public Component getComponent(
+ Table table,
+ PageState state,
+ Object value,
+ boolean isSelected,
+ Object key,
+ int row,
+ int column) {
+ Project2OrgaUnit p2ou = (Project2OrgaUnit) value;
+ boolean isFirst = (row == 0);
+ if (m_size.get(state) == null) {
+ m_size.set(state,
+ new Long(((Project2OrgaUnitTableModelBuilder.Project2OrgaUnitTableModel) table.getTableModel(state)).size()));
+ }
+ boolean isLast = (row == ((Long) m_size.get(state)).intValue() - 1);
+
+ String url = p2ou.getURI(state);
+ if (column == m_orgaUnitCol.getModelIndex()) {
+ ExternalLink extLink =
+ new ExternalLink(p2ou.getTargetItem().getOrganizationalUnitName(), url);
+ return extLink;
+ } else if (column == m_editCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ if (isSelected) {
+ return new Label(EDIT_EVENT, Label.BOLD);
+ } else {
+ return new ControlLink(EDIT_EVENT);
+ }
+ } else {
+ return new Label(EDIT_EVENT);
+ }
+ } else if (column == m_delCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ return new ControlLink(DELETE_EVENT);
+ } else {
+ return new Label(DELETE_EVENT);
+ }
+ } else if (column == m_moveUpCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state)) && !isFirst) {
+ Label downLabel = new Label(UP_EVENT);
+ downLabel.setClassAttr("linkSort");
+ return new ControlLink(downLabel);
+ } else {
+ return new Label("");
+ }
+ } else if (column == m_moveDownCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state)) && !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.");
+ }
+ }
+ }
+
+ private class Project2OrgaUnitTableActionListener
+ implements TableActionListener {
+
+ private Project2OrgaUnit getProject2OrgaUnit(TableActionEvent e) {
+ Object o = e.getRowKey();
+ BigDecimal id;
+ if (o instanceof String) {
+ id = new BigDecimal((String) o);
+ } else {
+ id = (BigDecimal) e.getRowKey();
+ }
+
+ Assert.exists(id);
+ Project2OrgaUnit p2ou;
+ try {
+ p2ou = (Project2OrgaUnit) DomainObjectFactory.newInstance(
+ new OID(Project2OrgaUnit.BASE_DATA_OBJECT_TYPE, id));
+ } catch(DataObjectNotFoundException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return p2ou;
+ }
+
+ public void cellSelected(TableActionEvent e) {
+ int col = e.getColumn().intValue();
+ PageState state = e.getPageState();
+ Project2OrgaUnit p2ou = getProject2OrgaUnit(e);
+ Assert.exists(p2ou);
+
+ if(col == m_editCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ m_p2ouModel.setSelectedObject(state, p2ou);
+ }
+ } else if(col == m_delCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ try {
+ m_p2ouModel.clearSelection(state);
+ p2ou.delete();
+ } catch(Exception ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+ }
+ } else if (col == m_moveUpCol.getModelIndex()) {
+ m_p2ouModel.clearSelection(state);
+ p2ou.swapWithPrevious();
+ } else if (col == m_moveDownCol.getModelIndex()) {
+ m_p2ouModel.clearSelection(state);
+ p2ou.swapWithNext();
+ }
+ }
+
+ public void headSelected(TableActionEvent e) {
+
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTableModelBuilder.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTableModelBuilder.java
new file mode 100644
index 000000000..d5486ab9f
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2OrgaUnitTableModelBuilder.java
@@ -0,0 +1,85 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.Table;
+import com.arsdigita.bebop.table.TableModel;
+import com.arsdigita.bebop.table.TableModelBuilder;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.Project2OrgaUnit;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.LockableImpl;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2OrgaUnitTableModelBuilder
+ extends LockableImpl
+ implements TableModelBuilder {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2OrgaUnitTableModelBuilder.class);
+ private ItemSelectionModel m_itemModel;
+
+ public Project2OrgaUnitTableModelBuilder(ItemSelectionModel itemModel) {
+ m_itemModel = itemModel;
+ }
+
+ public TableModel makeModel(Table t, PageState s) {
+ DataCollection units = getUnits(s);
+
+ if (units.isEmpty()) {
+ return Table.EMPTY_MODEL;
+ } else {
+ return new Project2OrgaUnitTableModel(units);
+ }
+ }
+
+ public DataCollection getUnits(PageState s) {
+ Assert.isTrue(m_itemModel.isSelected(s), "item selected");
+ Project project = (Project) m_itemModel.getSelectedItem(s);
+ return Project2OrgaUnit.getUnits(project);
+ }
+
+ public static class Project2OrgaUnitTableModel implements TableModel {
+
+ Project2OrgaUnit m_p2ou;
+ DataCollection m_units;
+
+ public Project2OrgaUnitTableModel(DataCollection units) {
+ m_units = units;
+ m_p2ou = null;
+ }
+
+ public int getColumnCount() {
+ return (int) m_units.size();
+ }
+
+ public boolean nextRow() {
+ if (m_units.next()) {
+ DataObject obj = m_units.getDataObject();
+ m_p2ou = (Project2OrgaUnit) DomainObjectFactory.newInstance(obj);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public Object getElementAt(int columnIndex) {
+ return m_p2ou;
+ }
+
+ public Object getKeyAt(int columnIndex) {
+ return m_p2ou.getID();
+ }
+
+ public long size() {
+ return m_units.size();
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertiesStep.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertiesStep.java
new file mode 100644
index 000000000..f91447c2b
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertiesStep.java
@@ -0,0 +1,78 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.Form;
+import com.arsdigita.bebop.FormSection;
+import com.arsdigita.bebop.Page;
+import com.arsdigita.bebop.SimpleContainer;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.ui.ResettableContainer;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedContainer;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2PersonPropertiesStep extends ResettableContainer {
+
+ private AuthoringKitWizard m_parent;
+ private ItemSelectionModel m_itemModel;
+ private BigDecimalParameter m_project2PersonParam =
+ new BigDecimalParameter("project2Person");
+ private Project2PersonSelectionModel m_project2PersonModel =
+ new Project2PersonSelectionModel(m_project2PersonParam);
+
+ public Project2PersonPropertiesStep(
+ ItemSelectionModel itemModel,
+ AuthoringKitWizard parent) {
+ m_itemModel = itemModel;
+ m_parent = parent;
+ setProject2PersonSelectionModel();
+ add(getDisplayComponent());
+
+ Form form = new Form("project2PersonEditForm");
+ form.add(getEditSheet());
+
+ WorkflowLockedContainer edit = new WorkflowLockedContainer(itemModel);
+ edit.add(form);
+ add(edit);
+ }
+
+ protected void setProject2PersonSelectionModel() {
+ setProject2PersonSelectionModel(
+ new Project2PersonSelectionModel(m_project2PersonParam));
+ }
+
+ protected void setProject2PersonSelectionModel(
+ Project2PersonSelectionModel model) {
+ m_project2PersonModel = model;
+ }
+
+ protected Project2PersonSelectionModel getProject2PersonSelectionModel() {
+ return m_project2PersonModel;
+ }
+
+ protected BigDecimalParameter getProject2PersonParameter() {
+ return m_project2PersonParam;
+ }
+
+ public Component getDisplayComponent() {
+ SimpleContainer container = new SimpleContainer();
+ container.add(new Project2PersonTable(m_itemModel,
+ m_project2PersonModel));
+ return container;
+ }
+
+ public FormSection getEditSheet() {
+ return new Project2PersonPropertyForm(m_itemModel,
+ m_project2PersonModel);
+ }
+
+ @Override
+ public void register(Page p) {
+ super.register(p);
+ p.addComponentStateParam(this, m_project2PersonParam);
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertyForm.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertyForm.java
new file mode 100644
index 000000000..53f352fe7
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonPropertyForm.java
@@ -0,0 +1,188 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.ColumnPanel;
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.FormSection;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.SaveCancelSection;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.event.FormSubmissionListener;
+import com.arsdigita.bebop.event.FormValidationListener;
+import com.arsdigita.bebop.event.PrintEvent;
+import com.arsdigita.bebop.event.PrintListener;
+import com.arsdigita.bebop.form.Submit;
+import com.arsdigita.cms.ContentType;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.Person;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.Project2Person;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.ui.ItemSearchWidget;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.UncheckedWrapperException;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2PersonPropertyForm
+ extends FormSection
+ implements FormInitListener,
+ FormProcessListener,
+ FormValidationListener,
+ FormSubmissionListener {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2PersonPropertyForm.class);
+ private ItemSelectionModel m_itemModel;
+ private Project2PersonSelectionModel m_project2PersonModel;
+ private ItemSearchWidget m_itemSearch;
+ private SaveCancelSection m_saveCancelSection;
+ private final String ITEM_SEARCH = "project2Person";
+
+ public Project2PersonPropertyForm(
+ ItemSelectionModel itemModel,
+ Project2PersonSelectionModel project2PersonModel) {
+ super(new ColumnPanel(2));
+ m_itemModel = itemModel;
+ m_project2PersonModel = project2PersonModel;
+
+ addWidgets();
+ addSaveCancelSection();
+
+ addInitListener(this);
+ addValidationListener(this);
+ addProcessListener(this);
+ addSubmissionListener(this);
+ }
+
+ protected void addWidgets() {
+ add(new Label(ProjectGlobalizationUtil.globalize(
+ "cms.contenttypes.ui.project.person")));
+ m_itemSearch = new ItemSearchWidget(ITEM_SEARCH,
+ ContentType.findByAssociatedObjectType(
+ "com.arsdigita.cms.contenttypes.Person"));
+ add(m_itemSearch);
+ }
+
+ public void addSaveCancelSection() {
+ m_saveCancelSection = new SaveCancelSection();
+ try {
+ m_saveCancelSection.getCancelButton().addPrintListener(new PrintListener() {
+
+ public void prepare(PrintEvent e) {
+ Submit target = (Submit) e.getTarget();
+ if (m_project2PersonModel.isSelected(e.getPageState())) {
+ target.setButtonLabel("Cancel");
+ } else {
+ target.setButtonLabel("Reset");
+ }
+ }
+ });
+
+ m_saveCancelSection.getSaveButton().addPrintListener(new PrintListener() {
+
+ public void prepare(PrintEvent e) {
+ Submit target = (Submit) e.getTarget();
+ if (m_project2PersonModel.isSelected(e.getPageState())) {
+ target.setButtonLabel("Save");
+ } else {
+ target.setButtonLabel("Create");
+ }
+ }
+ });
+ } catch (Exception ex) {
+ throw new UncheckedWrapperException("this cannot happen", ex);
+ }
+ add(m_saveCancelSection, ColumnPanel.FULL_WIDTH);
+ }
+
+ public SaveCancelSection getSaveCancelSection() {
+ return m_saveCancelSection;
+ }
+
+ protected Project2PersonSelectionModel getProject2PersonSelectionModel() {
+ return m_project2PersonModel;
+ }
+
+ protected Project getProject(PageState s) {
+ return (Project) m_itemModel.getSelectedItem(s);
+ }
+
+ protected Project2Person createProject2Person(PageState s) {
+ Project project = getProject(s);
+ Assert.exists(project);
+ Project2Person project2Person = new Project2Person();
+ project2Person.setProject(project);
+ return project2Person;
+ }
+
+ protected void setProject2PersonProperties(
+ Project2Person project2Person,
+ FormSectionEvent e) {
+ PageState state = e.getPageState();
+ FormData data = e.getFormData();
+
+ project2Person.setTargetItem((Person) data.get(ITEM_SEARCH));
+
+ project2Person.save();
+ }
+
+ public void init(FormSectionEvent e) throws FormProcessException {
+ FormData data = e.getFormData();
+ PageState state = e.getPageState();
+
+ setVisible(state, true);
+
+ Project2Person project2Person;
+ if (m_project2PersonModel.isSelected(state)) {
+ project2Person = m_project2PersonModel.getSelectedP2P(state);
+ try {
+ data.put(ITEM_SEARCH, project2Person.getTargetItem());
+ } catch(IllegalStateException ex) {
+ throw ex;
+ }
+ } else {
+ data.put(ITEM_SEARCH, null);
+ }
+ }
+
+ public void process(FormSectionEvent e) throws FormProcessException {
+ PageState state = e.getPageState();
+ Project2Person project2Person;
+
+ if (getSaveCancelSection().getCancelButton().isSelected(state)) {
+ m_project2PersonModel.clearSelection(state);
+ } else {
+ if (m_project2PersonModel.isSelected(state)) {
+ project2Person = m_project2PersonModel.getSelectedP2P(state);
+ } else {
+ project2Person = createProject2Person(state);
+ }
+ setProject2PersonProperties(project2Person, e);
+ }
+
+ m_project2PersonModel.clearSelection(state);
+ init(e);
+ }
+
+ public void validate(FormSectionEvent e) throws FormProcessException {
+ if (e.getFormData().get(ITEM_SEARCH) == null) {
+ throw new FormProcessException("Person selection is required");
+ }
+ }
+
+ public void submitted(FormSectionEvent e) throws FormProcessException {
+ if (m_saveCancelSection.getCancelButton().isSelected(
+ e.getPageState())) {
+ m_project2PersonModel.clearSelection(e.getPageState());
+ init(e);
+ throw new FormProcessException("cancelled");
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonSelectionModel.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonSelectionModel.java
new file mode 100644
index 000000000..7b9740696
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonSelectionModel.java
@@ -0,0 +1,31 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.cms.contenttypes.Project2Person;
+import com.arsdigita.kernel.ui.ACSObjectSelectionModel;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2PersonSelectionModel extends ACSObjectSelectionModel {
+
+ public Project2PersonSelectionModel(BigDecimalParameter param) {
+ super(Project2Person.class.getName(),
+ Project2Person.BASE_DATA_OBJECT_TYPE,
+ param);
+ }
+
+ public Project2PersonSelectionModel(
+ String itemClass,
+ String objectType,
+ BigDecimalParameter param) {
+ super(itemClass, objectType, param);
+ }
+
+ public Project2Person getSelectedP2P(PageState s) {
+ return (Project2Person) getSelectedObject(s);
+ }
+
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTable.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTable.java
new file mode 100644
index 000000000..75474ea8b
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTable.java
@@ -0,0 +1,243 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui.project;
+
+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.table.TableCellRenderer;
+import com.arsdigita.bebop.table.TableColumn;
+import com.arsdigita.bebop.table.TableColumnModel;
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.SecurityManager;
+import com.arsdigita.cms.contenttypes.Person;
+import com.arsdigita.cms.contenttypes.Project2Person;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.dispatcher.Utilities;
+import com.arsdigita.domain.DataObjectNotFoundException;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.UncheckedWrapperException;
+import java.math.BigDecimal;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2PersonTable extends Table {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2PersonTable.class);
+ private Project2PersonSelectionModel m_project2personModel;
+ private ItemSelectionModel m_itemModel;
+ private TableColumn m_personCol;
+ private TableColumn m_editCol;
+ private TableColumn m_delCol;
+ private TableColumn m_moveUpCol;
+ private TableColumn m_moveDownCol;
+ private RequestLocal m_size;
+ private RequestLocal m_editor;
+ protected final static String EDIT_EVENT = "Edit";
+ protected final static String DELETE_EVENT = "Delete";
+ protected final static String UP_EVENT = "up";
+ protected final static String DOWN_EVENT = "down";
+
+ public Project2PersonTable(
+ ItemSelectionModel itemModel,
+ Project2PersonSelectionModel project2PersonModel) {
+ super();
+ m_itemModel = itemModel;
+ m_project2personModel = project2PersonModel;
+ addColumns();
+
+ m_size = new RequestLocal();
+ m_editor = new RequestLocal() {
+
+ @Override
+ public Object initialValue(PageState s) {
+ SecurityManager sm = Utilities.getSecurityManager(s);
+ ContentItem item = m_itemModel.getSelectedItem(s);
+ Boolean val = new Boolean(sm.canAccess(s.getRequest(), SecurityManager.EDIT_ITEM, item));
+ return val;
+ }
+ };
+
+ Label empty = new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.noPersonsAssociated"));
+ setEmptyView(empty);
+ addTableActionListener(new Project2PersonTableActionListener());
+ setRowSelectionModel(project2PersonModel);
+ setDefaultCellRenderer(new Project2PersonTableRenderer());
+ setModelBuilder(new Project2PersonTableModelBuilder(itemModel));
+ }
+
+ public void addColumns() {
+ TableColumnModel model = getColumnModel();
+
+ m_personCol = new TableColumn(0,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.person").localize());
+ m_editCol = new TableColumn(1,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.edit").localize());
+ m_delCol = new TableColumn(2,
+ ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project_del").localize());
+ m_moveUpCol = new TableColumn(3, "");
+ m_moveDownCol = new TableColumn(4, "");
+
+ model.add(m_personCol);
+ model.add(m_editCol);
+ model.add(m_delCol);
+ model.add(m_moveUpCol);
+ model.add(m_moveDownCol);
+ setColumnModel(model);
+ }
+
+ private class Project2PersonTableRenderer implements TableCellRenderer {
+
+ public Component getComponent(
+ Table table,
+ PageState state,
+ Object value,
+ boolean isSelected,
+ Object key,
+ int row,
+ int column) {
+ Project2Person project2Person = (Project2Person) value;
+ boolean isFirst = (row == 0);
+ if (m_size.get(state) == null) {
+ m_size.set(state,
+ new Long(((Project2PersonTableModelBuilder.Project2PersonTableModel) table.getTableModel(state)).size()));
+ }
+ boolean isLast = (row == ((Long) m_size.get(state)).intValue() - 1);
+
+ String url = project2Person.getURI(state);
+ if (column == m_personCol.getModelIndex()) {
+ Person person = project2Person.getTargetItem();
+ StringBuilder fullNameBuilder = new StringBuilder();
+
+ if (person.getTitlePre() != null) {
+ fullNameBuilder.append(person.getTitlePre());
+ fullNameBuilder.append(" ");
+ }
+ if (person.getGivenName() != null) {
+ fullNameBuilder.append(person.getGivenName());
+ fullNameBuilder.append(" ");
+ }
+ if (person.getSurname() != null) {
+ fullNameBuilder.append(person.getSurname());
+ fullNameBuilder.append(" ");
+ }
+ if (person.getTitlePost() != null) {
+ fullNameBuilder.append(person.getTitlePost());
+ }
+ String fullName = fullNameBuilder.toString();
+
+ ExternalLink extLink = new ExternalLink(fullName, url);
+ return extLink;
+ } else if (column == m_editCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ if (isSelected) {
+ return new Label(EDIT_EVENT, Label.BOLD);
+ } else {
+ return new ControlLink(EDIT_EVENT);
+ }
+ } else {
+ return new Label(EDIT_EVENT);
+ }
+ } else if (column == m_delCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ return new ControlLink(DELETE_EVENT);
+ } else {
+ return new Label(DELETE_EVENT);
+ }
+ } else if (column == m_moveUpCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state)) && !isFirst) {
+ Label downLabel = new Label(UP_EVENT);
+ downLabel.setClassAttr("linkSort");
+ return new ControlLink(downLabel);
+ } else {
+ return new Label("");
+ }
+ } else if (column == m_moveDownCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state)) && !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.");
+ }
+ }
+ }
+
+ private class Project2PersonTableActionListener
+ implements TableActionListener {
+
+ private Project2Person getProject2Person(TableActionEvent e) {
+ Object o = e.getRowKey();
+ BigDecimal id;
+ if (o instanceof String) {
+ id = new BigDecimal((String) o);
+ } else {
+ id = (BigDecimal) e.getRowKey();
+ }
+
+ Assert.exists(id);
+ Project2Person project2Person;
+ try {
+ project2Person = (Project2Person) DomainObjectFactory.newInstance(
+ new OID(Project2Person.BASE_DATA_OBJECT_TYPE, id));
+ } catch (DataObjectNotFoundException ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+
+ return project2Person;
+ }
+
+ public void cellSelected(TableActionEvent e) {
+ s_log.debug("this is cellSelected...");
+ int col = e.getColumn().intValue();
+ PageState state = e.getPageState();
+ Project2Person project2Person = getProject2Person(e);
+ Assert.exists(project2Person);
+
+ if (col == m_editCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ m_project2personModel.setSelectedObject(state,
+ project2Person);
+ }
+ } else if (col == m_delCol.getModelIndex()) {
+ if (Boolean.TRUE.equals(m_editor.get(state))) {
+ try {
+ m_project2personModel.clearSelection(state);
+ s_log.debug("trying to delete project2Person...");
+ project2Person.delete();
+ } catch (Exception ex) {
+ throw new UncheckedWrapperException(ex);
+ }
+ }
+ } else if (col == m_moveUpCol.getModelIndex()) {
+ m_project2personModel.clearSelection(state);
+ project2Person.swapWithPrevious();
+ } else if (col == m_moveDownCol.getModelIndex()) {
+ m_project2personModel.clearSelection(state);
+ project2Person.swapWithNext();
+ }
+ }
+
+ public void headSelected(TableActionEvent e) {
+ }
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTableModelBuilder.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTableModelBuilder.java
new file mode 100644
index 000000000..558a84c73
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/Project2PersonTableModelBuilder.java
@@ -0,0 +1,86 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.Table;
+import com.arsdigita.bebop.table.TableModel;
+import com.arsdigita.bebop.table.TableModelBuilder;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.Project2Person;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.LockableImpl;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class Project2PersonTableModelBuilder
+ extends LockableImpl
+ implements TableModelBuilder {
+
+ private final static Logger s_log =
+ Logger.getLogger(Project2PersonTableModelBuilder.class);
+ private ItemSelectionModel m_itemModel;
+
+ public Project2PersonTableModelBuilder(ItemSelectionModel itemModel) {
+ m_itemModel = itemModel;
+ }
+
+ public TableModel makeModel(Table t, PageState s) {
+ DataCollection persons = getPersons(s);
+
+ if (persons.isEmpty()) {
+ return Table.EMPTY_MODEL;
+ } else {
+ return new Project2PersonTableModel(persons);
+ }
+ }
+
+ public DataCollection getPersons(PageState s) {
+ Assert.isTrue(m_itemModel.isSelected(s), "item selected");
+ Project project = (Project) m_itemModel.getSelectedItem(s);
+ return Project2Person.getProject2Persons(project);
+ }
+
+ public static class Project2PersonTableModel implements TableModel {
+
+ DataCollection m_persons;
+ Project2Person m_p2p;
+
+ public Project2PersonTableModel(DataCollection persons) {
+ m_persons = persons;
+ m_p2p = null;
+ }
+
+ public int getColumnCount() {
+ return (int) m_persons.size();
+ }
+
+ public boolean nextRow() {
+ if (m_persons.next()) {
+ DataObject obj = m_persons.getDataObject();
+ m_p2p = (Project2Person) DomainObjectFactory.newInstance(obj);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public Object getElementAt(int columnIndex) {
+ return m_p2p;
+ }
+
+ public Object getKeyAt(int columnIndex) {
+ return m_p2p.getID();
+ }
+
+ public long size() {
+ return m_persons.size();
+ }
+
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertiesStep.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertiesStep.java
new file mode 100644
index 000000000..0607838f1
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertiesStep.java
@@ -0,0 +1,69 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.util.GlobalizationUtil;
+import com.arsdigita.cms.ContentPage;
+import com.arsdigita.cms.ContentSection;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.authoring.BasicPageForm;
+import com.arsdigita.cms.ui.authoring.SimpleEditStep;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
+import com.arsdigita.domain.DomainObject;
+import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
+import java.text.DateFormat;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProjectPropertiesStep extends SimpleEditStep {
+
+ private final static Logger s_log = Logger.getLogger(ProjectPropertiesStep.class);
+ public final static String EDIT_SHEET_NAME = "edit";
+
+ public ProjectPropertiesStep(ItemSelectionModel itemModel, AuthoringKitWizard parent) {
+ super(itemModel, parent);
+
+ setDefaultEditKey(EDIT_SHEET_NAME);
+
+ BasicPageForm editSheet;
+ editSheet = new ProjectPropertyForm(itemModel, this);
+ add(EDIT_SHEET_NAME, "Edit",
+ new WorkflowLockedComponentAccess(editSheet, itemModel),
+ editSheet.getSaveCancelSection().getCancelButton());
+
+ setDisplayComponent(getProjectPropertySheet(itemModel));
+ }
+
+ public static Component getProjectPropertySheet(ItemSelectionModel itemModel) {
+ DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel);
+
+ sheet.add(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.projectname"),
+ Project.PROJECTNAME);
+ sheet.add(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.description"),
+ Project.PROJECT_DESCRIPTION);
+
+ if (!ContentSection.getConfig().getHideLaunchDate()) {
+ sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"),
+ ContentPage.LAUNCH_DATE,
+ new DomainObjectPropertySheet.AttributeFormatter() {
+
+ public String format(DomainObject obj, String attribute, PageState state) {
+ ContentPage page = (ContentPage) obj;
+ if (page.getLaunchDate() != null) {
+ return DateFormat.getDateInstance(DateFormat.LONG).format(page.getLaunchDate());
+ } else {
+ return (String) GlobalizationUtil.globalize("cms.ui.unknown").localize();
+ }
+ }
+ });
+ }
+
+ return sheet;
+ }
+}
diff --git a/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertyForm.java b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertyForm.java
new file mode 100644
index 000000000..cfd386bfe
--- /dev/null
+++ b/ccm-cms-types-project/src/com/arsdigita/cms/contenttypes/ui/project/ProjectPropertyForm.java
@@ -0,0 +1,128 @@
+package com.arsdigita.cms.contenttypes.ui.project;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.event.FormSubmissionListener;
+import com.arsdigita.bebop.form.Date;
+import com.arsdigita.bebop.form.TextArea;
+import com.arsdigita.bebop.form.TextField;
+import com.arsdigita.bebop.parameters.DateParameter;
+import com.arsdigita.bebop.parameters.NotNullValidationListener;
+import com.arsdigita.bebop.parameters.ParameterModel;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.contenttypes.Project;
+import com.arsdigita.cms.contenttypes.ProjectGlobalizationUtil;
+import com.arsdigita.cms.ui.authoring.BasicPageForm;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProjectPropertyForm extends BasicPageForm
+ implements FormProcessListener, FormInitListener, FormSubmissionListener {
+
+ private final static Logger s_log = Logger.getLogger(ProjectPropertyForm.class);
+ private ProjectPropertiesStep m_step;
+ public final static String PROJECTNAME = Project.PROJECTNAME;
+ public final static String PROJECT_DESCRIPTION = Project.PROJECT_DESCRIPTION;
+ public final static String FUNDING = Project.FUNDING;
+ public final static String BEGINDATE = Project.BEGINDATE;
+ public final static String ENDDATE = Project.ENDDATE;
+ //public final static String FINISHED = Project.FINISHED;
+ public final static String ID = "Project_edit";
+
+ public ProjectPropertyForm(ItemSelectionModel itemModel) {
+ this(itemModel, null);
+ }
+
+ public ProjectPropertyForm(ItemSelectionModel itemModel,
+ ProjectPropertiesStep step) {
+ super(ID, itemModel);
+ s_log.debug("Creating PropertyForm for project...");
+ m_step = step;
+ addSubmissionListener(this);
+ }
+
+ @Override
+ public void addWidgets() {
+ s_log.debug("addWidgets called...");
+ s_log.debug("Adding widgets of super class...");
+ super.addWidgets();
+
+ s_log.debug("Adding own widgets...");
+ add(new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.projectname")));
+ ParameterModel projectNameParam = new StringParameter(PROJECTNAME);
+ TextField projectName = new TextField(projectNameParam);
+ projectName.addValidationListener(new NotNullValidationListener());
+ add(projectName);
+
+ add(new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.description")));
+ TextArea description = new TextArea(PROJECT_DESCRIPTION);
+ description.setRows(5);
+ description.setCols(30);
+ add(description);
+
+ add(new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.funding")));
+ TextArea funding = new TextArea(FUNDING);
+ funding.setRows(5);
+ funding.setCols(30);
+ add(funding);
+
+ add(new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.begin")));
+ ParameterModel beginParam = new DateParameter(BEGINDATE);
+ Date begin = new Date(beginParam);
+ add(begin);
+
+ add(new Label(ProjectGlobalizationUtil.globalize("cms.contenttypes.ui.project.end")));
+ ParameterModel endParam = new DateParameter(ENDDATE);
+ Date end = new Date(endParam);
+ add(end);
+ }
+
+ @Override
+ public void init(FormSectionEvent e) throws FormProcessException {
+ FormData data = e.getFormData();
+ Project project = (Project) super.initBasicWidgets(e);
+
+ data.put(PROJECTNAME, project.getProjectName());
+ data.put(PROJECT_DESCRIPTION, project.getProjectDescription());
+ data.put(FUNDING, project.getFunding());
+ data.put(BEGINDATE, project.getBegin());
+ data.put(ENDDATE, project.getEnd());
+ }
+
+ @Override
+ public void process(FormSectionEvent e) throws FormProcessException {
+ FormData data = e.getFormData();
+
+ Project project = (Project) super.processBasicWidgets(e);
+
+ if ((project != null) &&
+ (getSaveCancelSection().getSaveButton().isSelected(e.getPageState()))) {
+ project.setProjectName((String) data.get(PROJECTNAME));
+ project.setProjectDescription((String) data.get(PROJECT_DESCRIPTION));
+ project.setFunding((String) data.get(FUNDING));
+ project.setBegin((java.util.Date) data.get(BEGINDATE));
+ project.setEnd((java.util.Date) data.get(ENDDATE));
+
+ project.save();
+ }
+
+ if (m_step != null) {
+ m_step.maybeForwardToNextStep(e.getPageState());
+ }
+ }
+
+ public void submitted(FormSectionEvent e) throws FormProcessException {
+ if ((m_step != null) &&
+ (getSaveCancelSection().getCancelButton().isSelected(e.getPageState()))) {
+ m_step.cancelStreamlinedCreation(e.getPageState());
+ }
+ }
+}
diff --git a/ccm-core/src/com/redhat/persistence/oql/Code.java b/ccm-core/src/com/redhat/persistence/oql/Code.java
index 4bbd456be..6b267a3fa 100755
--- a/ccm-core/src/com/redhat/persistence/oql/Code.java
+++ b/ccm-core/src/com/redhat/persistence/oql/Code.java
@@ -566,7 +566,7 @@ public class Code {
return names(cols(c, type), alias);
}
- private static Column[] cols(Constraint c, ObjectType type) {
+ private static Column[] cols(Constraint c, ObjectType type) {
Column[] cols = c.getColumns();
Root root = type.getRoot();
ObjectType basetype = type.getBasetype();