diff --git a/ccm-sci-personalpublications/application.xml b/ccm-sci-personalpublications/application.xml
new file mode 100644
index 000000000..aeff43938
--- /dev/null
+++ b/ccm-sci-personalpublications/application.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content generator creating a list of the publications of a person.
+
+
diff --git a/ccm-sci-personalpublications/src/ccm-sci-personalpublications.config b/ccm-sci-personalpublications/src/ccm-sci-personalpublications.config
new file mode 100644
index 000000000..1b5a291f9
--- /dev/null
+++ b/ccm-sci-personalpublications/src/ccm-sci-personalpublications.config
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/ccm-sci-personalpublications/src/ccm-sci-personalpublications.load b/ccm-sci-personalpublications/src/ccm-sci-personalpublications.load
new file mode 100644
index 000000000..04c72602d
--- /dev/null
+++ b/ccm-sci-personalpublications/src/ccm-sci-personalpublications.load
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublications.java b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublications.java
new file mode 100644
index 000000000..e996c5672
--- /dev/null
+++ b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublications.java
@@ -0,0 +1,227 @@
+package com.arsdigita.cms.publicpersonalprofile;
+
+import com.arsdigita.cms.contenttypes.AuthorshipCollection;
+import com.arsdigita.cms.contenttypes.GenericPerson;
+import com.arsdigita.cms.contenttypes.Publication;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.xml.Element;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @version $Id$
+ */
+public class PersonalPublications implements ContentGenerator {
+
+ private final static String MISC = "misc";
+ private final static PersonalPublicationsConfig config =
+ new PersonalPublicationsConfig();
+ private final static Logger logger = Logger.getLogger(
+ PersonalPublications.class);
+
+ static {
+ config.load();
+ }
+
+ public void generateContent(final Element parent,
+ final GenericPerson person) {
+ DataCollection publications = (DataCollection) person.get("publication");
+
+ if ((publications == null) || publications.size() == 0) {
+ final Element publicationsElem = parent.newChildElement(
+ "publications");
+ publicationsElem.newChildElement("noPublications");
+
+ return;
+ } else {
+ final Map> groupedPublications =
+ processPublications(
+ publications);
+
+ generateGroupsXml(parent, groupedPublications);
+ generatePublicationsXml(parent, groupedPublications);
+ }
+ }
+
+ /**
+ * Processes the publications and puts them into the groups.
+ *
+ * @param publications The publications to process
+ * @param typeGroupMap The group-type map
+ * @return A map with the group names as keys and a list of publications
+ * as value.
+ */
+ private Map> processPublications(
+ final DataCollection publications) {
+
+ final GroupConfig groupConfig = new GroupConfig(config.
+ getPublictionGroups());
+ final Map> pubGroups =
+ new LinkedHashMap>();
+
+ for (String group : groupConfig.getGroups()) {
+ initalizePubGroupMap(pubGroups, group);
+ }
+ initalizePubGroupMap(pubGroups, MISC);
+
+ DataObject dobj;
+ Publication publication;
+ String type;
+ String groupName;
+ Boolean reviewed;
+ List group;
+ while (publications.next()) {
+ dobj = publications.getDataObject();
+ publication = (Publication) DomainObjectFactory.newInstance(dobj);
+ type = publication.getClass().getName();
+
+ if (dobj.getObjectType().hasProperty("reviewed")) {
+ reviewed = (Boolean) dobj.get("reviewed");
+ if (reviewed) {
+ groupName = groupConfig.getTypeGroupMap().get(String.format(
+ "%s_ref", type));
+ } else {
+ groupName = groupConfig.getTypeGroupMap().get(String.format(
+ "%s_noref", type));
+ }
+
+ if (groupName == null) {
+ groupName = groupConfig.getTypeGroupMap().get(type);
+ }
+ } else {
+ groupName = groupConfig.getTypeGroupMap().get(type);
+ }
+
+ if (groupName == null) {
+ groupName = MISC;
+ }
+
+ group = pubGroups.get(groupName);
+ group.add(publication);
+ }
+
+ final PublicationGroupComparator comparator =
+ new PublicationGroupComparator();
+ for (List currentGroup : pubGroups.values()) {
+ Collections.sort(currentGroup, comparator);
+ }
+
+ return pubGroups;
+ }
+
+ private void initalizePubGroupMap(
+ final Map> pubGroups,
+ final String groupName) {
+ pubGroups.put(groupName, new ArrayList());
+ }
+
+ private void generateGroupsXml(final Element parent,
+ final Map> publications) {
+ }
+
+ private void generatePublicationsXml(final Element parent,
+ final Map> publications) {
+ }
+
+ private void generatePublicationXml(final Element publicationsElem,
+ final Publication publication) {
+ }
+
+ /**
+ * Processes the publications and puts them into the groups.
+ *
+ * @param publications The publications to process
+ * @param typeGroupMap The group-type map
+ * @return A map with the group names as keys and a list of publications
+ * as value.
+ */
+ private class GroupConfig {
+
+ private final Map typeGroupMap =
+ new HashMap();
+ private final List groups = new ArrayList();
+
+ /**
+ * Processes the configuration string and puts the result into the
+ * collections.
+ *
+ * @param groupStr
+ */
+ public GroupConfig(final String groupStr) {
+ final String[] groupTokens = groupStr.split(";");
+ String[] groupTokenSplit;
+ String groupName;
+ String publicationTypeTokens;
+ String[] publicationTypeTokensSplit;
+ List types;
+ for (String groupToken : groupTokens) {
+ groupTokenSplit = groupToken.split(":");
+ if (groupTokenSplit.length != 2) {
+ logger.debug(String.format(
+ "Invalid entry in publication group config: '%s'. "
+ + "Ignoring.",
+ groupToken));
+ continue;
+ }
+
+ groupName = groupTokenSplit[0];
+ groups.add(groupName);
+ publicationTypeTokens = groupTokenSplit[1];
+ publicationTypeTokensSplit = publicationTypeTokens.split(",");
+ for (String publicationTypeToken : publicationTypeTokensSplit) {
+ typeGroupMap.put(publicationTypeToken, groupName);
+ }
+ }
+ }
+
+ public Map getTypeGroupMap() {
+ return Collections.unmodifiableMap(typeGroupMap);
+ }
+
+ public List getGroups() {
+ return Collections.unmodifiableList(groups);
+ }
+ }
+
+ private class PublicationGroupComparator implements Comparator {
+
+ public int compare(final Publication publication1,
+ final Publication publication2) {
+ AuthorshipCollection authors1;
+ AuthorshipCollection authors2;
+ GenericPerson author;
+ String authorsStr1;
+ String authorsStr2;
+ final StringBuffer authors1Buffer = new StringBuffer();
+ final StringBuffer authors2Buffer = new StringBuffer();
+
+ authors1 = publication1.getAuthors();
+ while (authors1.next()) {
+ author = authors1.getAuthor();
+ authors1Buffer.append(author.getSurname());
+ authors1Buffer.append(author.getGivenName());
+ }
+ authors2 = publication2.getAuthors();
+ while (authors2.next()) {
+ author = authors1.getAuthor();
+ authors2Buffer.append(author.getSurname());
+ authors2Buffer.append(author.getGivenName());
+ }
+
+ authorsStr1 = authors1Buffer.toString();
+ authorsStr2 = authors2Buffer.toString();
+
+ return authorsStr1.compareTo(authorsStr2);
+ }
+ }
+}
diff --git a/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig.java b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig.java
new file mode 100644
index 000000000..3de1a3f1e
--- /dev/null
+++ b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig.java
@@ -0,0 +1,39 @@
+package com.arsdigita.cms.publicpersonalprofile;
+
+import com.arsdigita.runtime.AbstractConfig;
+import com.arsdigita.util.parameter.Parameter;
+import com.arsdigita.util.parameter.StringParameter;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @version $Id$
+ */
+public class PersonalPublicationsConfig extends AbstractConfig {
+
+ /**
+ * Groups of publications. See {@link PersonalPublications} for a detailed
+ * explanation.
+ */
+ private final Parameter publicationGroups;
+
+ public PersonalPublicationsConfig() {
+ publicationGroups =
+ new StringParameter(
+ "com.arsdigita.cms.publicpersonalprofile.publications.groups",
+ Parameter.REQUIRED,
+ "monographs:com.arsdigita.cms.contenttypes.Monograph;"
+ + "collectedVolumeArticles:com.arsdigita.cms.contenttypes.ArticleInCollectedVolume;"
+ + "journalArticles:com.arsdigita.cms.contenttypes.ArticleInJournal;"
+ + "journalArticlesRef:com.arsdigita.cms.contenttypes.ArticleInJournal_ref"
+ + "collectedVolumes:com.arsdigita.cms.contenttypes.CollectedVolume");
+
+ register(publicationGroups);
+
+ loadInfo();
+ }
+
+ public final String getPublictionGroups() {
+ return (String) get(publicationGroups);
+ }
+}
diff --git a/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig_parameters.properties b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig_parameters.properties
new file mode 100644
index 000000000..a7f4ac0be
--- /dev/null
+++ b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsConfig_parameters.properties
@@ -0,0 +1,4 @@
+com.arsdigita.cms.publicpersonalprofile.publications.groups.title = Groups of publications
+com.arsdigita.cms.publicpersonalprofile.publications.groups.purpose = Groups the publications of a person by their Type and optional the Property "Referenced". See the JavaDoc of com.arsdigita.cms.publicpersonalprofile.PersonalPublications for a detailed explanation of the syntax of this parameter
+com.arsdigita.cms.publicpersonalprofile.publications.groups.example = monographs:com.arsdigita.cms.contenttypes.Monograph;collectedVolumeArticles:com.arsdigita.cms.contenttypes.ArticleInCollectedVolume;journalArticles:com.arsdigita.cms.contenttypes.ArticleInJournal;journalArticlesRef:com.arsdigita.cms.contenttypes.ArticleInJournal_ref;collectedVolumes:com.arsdigita.cms.contenttypes.CollectedVolume
+com.arsdigita.cms.publicpersonalprofile.publications.groups.format = [String]
\ No newline at end of file
diff --git a/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsInitializer.java b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsInitializer.java
new file mode 100644
index 000000000..555b04de0
--- /dev/null
+++ b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsInitializer.java
@@ -0,0 +1,32 @@
+package com.arsdigita.cms.publicpersonalprofile;
+
+import com.arsdigita.db.DbHelper;
+import com.arsdigita.persistence.pdl.ManifestSource;
+import com.arsdigita.persistence.pdl.NameFilter;
+import com.arsdigita.runtime.CompoundInitializer;
+import com.arsdigita.runtime.DomainInitEvent;
+import com.arsdigita.runtime.PDLInitializer;
+import com.arsdigita.runtime.RuntimeConfig;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @version $Id$
+ */
+public class PersonalPublicationsInitializer extends CompoundInitializer {
+
+ public PersonalPublicationsInitializer() {
+
+ final String jdbcUrl = RuntimeConfig.getConfig().getJDBCURL();
+ final int database = DbHelper.getDatabaseFromURL(jdbcUrl);
+
+ add(new PDLInitializer(new ManifestSource("empty.pdl.mf",
+ new NameFilter(DbHelper.
+ getDatabaseSuffix(database), "pdl"))));
+ }
+
+ @Override
+ public void init(final DomainInitEvent event) {
+ super.init(event);
+ }
+}
diff --git a/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsLoader.java b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsLoader.java
new file mode 100644
index 000000000..5d694e501
--- /dev/null
+++ b/ccm-sci-personalpublications/src/com/arsdigita/cms/publicpersonalprofile/PersonalPublicationsLoader.java
@@ -0,0 +1,17 @@
+package com.arsdigita.cms.publicpersonalprofile;
+
+import com.arsdigita.loader.PackageLoader;
+import com.arsdigita.runtime.ScriptContext;
+
+/**
+ *
+ * @author Jens Pelzetter
+ * @version $Id$
+ */
+public class PersonalPublicationsLoader extends PackageLoader {
+
+ @Override
+ public void run(final ScriptContext ctx) {
+ //Nothing to do.
+ }
+}
diff --git a/ccm-sci-personalpublications/src/empty.pdl.mf b/ccm-sci-personalpublications/src/empty.pdl.mf
new file mode 100644
index 000000000..e69de29bb