diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemController.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemController.java
new file mode 100644
index 000000000..8be70516b
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemController.java
@@ -0,0 +1,117 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import org.librecms.assets.Person;
+import org.librecms.contentsection.AssetRepository;
+import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.transaction.Transactional;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+class ProfileSiteItemController {
+
+ public static final String OWNER = "owner";
+
+ public static final String POSITION = "position";
+
+ public static final String INTERSETS = "interests";
+
+ public static final String MISC = "misc";
+
+ @Inject
+ private AssetRepository assetRepository;
+
+ @Inject
+ private ContentItemRepository itemRepository;
+
+ @Transactional(Transactional.TxType.REQUIRED)
+ public void setOwner(final long profileSiteItemId, final long ownerId) {
+ final ProfileSiteItem profileSiteItem = itemRepository
+ .findById(profileSiteItemId, ProfileSiteItem.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No ProfileSiteItem with ID %d found.",
+ profileSiteItemId
+ )
+ )
+ );
+
+ final Person owner = assetRepository
+ .findById(ownerId, Person.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No Person with ID %d found.", ownerId
+ )
+ )
+ );
+
+ profileSiteItem.setOwner(owner);
+ itemRepository.save(profileSiteItem);
+ }
+
+ public void setPosition(
+ final long profileSiteItemId, final String position, final Locale locale
+ ) {
+ final ProfileSiteItem profileSiteItem = itemRepository
+ .findById(profileSiteItemId, ProfileSiteItem.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No ProfileSiteItem with ID %d found.",
+ profileSiteItemId
+ )
+ )
+ );
+ profileSiteItem.getPosition().addValue(locale, position);
+ }
+
+ public void setInterests(
+ final long profileSiteItemId,
+ final String interests,
+ final Locale locale
+ ) {
+ final ProfileSiteItem profileSiteItem = itemRepository
+ .findById(profileSiteItemId, ProfileSiteItem.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No ProfileSiteItem with ID %d found.",
+ profileSiteItemId
+ )
+ )
+ );
+ profileSiteItem.getInterests().addValue(locale, interests);
+ }
+
+ public void setMisc(
+ final long profileSiteItemId, final String misc, final Locale locale
+ ) {
+ final ProfileSiteItem profileSiteItem = itemRepository
+ .findById(profileSiteItemId, ProfileSiteItem.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No ProfileSiteItem with ID %d found.",
+ profileSiteItemId
+ )
+ )
+ );
+ profileSiteItem.getMisc().addValue(locale, misc);
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemCreate.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemCreate.java
new file mode 100644
index 000000000..7b842f43a
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemCreate.java
@@ -0,0 +1,80 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.assets.AssetSearchWidget;
+import com.arsdigita.cms.ui.authoring.CreationSelector;
+import com.arsdigita.cms.ui.authoring.PageCreateForm;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.librecms.assets.Person;
+import org.librecms.contentsection.ContentItemInitializer;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemCreate extends PageCreateForm {
+
+ private final static String OWNER_SEARCH = "owner";
+
+ private AssetSearchWidget ownerSearch;
+
+ public ProfileSiteItemCreate(
+ final ItemSelectionModel itemModel,
+ final CreationSelector creationSelector,
+ final StringParameter selectedLanguageParam
+ ) {
+ super(itemModel, creationSelector, selectedLanguageParam);
+ }
+
+ @Override
+ public void addWidgets() {
+ ownerSearch = new AssetSearchWidget(OWNER_SEARCH, Person.class);
+ ownerSearch.setLabel(
+ new GlobalizedMessage(
+ "profile_site.owner.label", ProfileSiteConstants.BUNDLE
+ )
+ );
+ add(ownerSearch);
+ }
+
+ @Override
+ public void validate(final FormSectionEvent event)
+ throws FormProcessException {
+ super.validate(event);
+ final FormData formData = event.getFormData();
+
+ if (!formData.containsKey(OWNER_SEARCH)
+ || formData.get(OWNER_SEARCH) == null) {
+ formData.addError(
+ new GlobalizedMessage(
+ "profile_site.owner.not_selected",
+ ProfileSiteConstants.BUNDLE
+ )
+ );
+ }
+ }
+
+ @Override
+ protected ContentItemInitializer getItemInitializer(
+ final FormData formData, final PageState state
+ ) {
+ return (item) -> item.setOwner((Person) formData.get(OWNER_SEARCH));
+ }
+
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsForm.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsForm.java
new file mode 100644
index 000000000..0e7c4997f
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsForm.java
@@ -0,0 +1,108 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.form.TextArea;
+import com.arsdigita.bebop.parameters.ParameterModel;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SelectedLanguageUtil;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.libreccm.cdi.utils.CdiUtil;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemInterestsForm
+ extends BasicItemForm
+ implements FormProcessListener, FormInitListener {
+
+ private final StringParameter selectedLangParam;
+
+ public ProfileSiteItemInterestsForm(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ super("ProfileSiteItemEditInterests", itemModel, selectedLangParam);
+ this.selectedLangParam = selectedLangParam;
+ }
+
+ @Override
+ public void addWidgets() {
+ add(
+ new Label(
+ new GlobalizedMessage(
+ "profile_site_item.ui.interests",
+ ProfileSiteConstants.BUNDLE
+ )
+ )
+ );
+ final ParameterModel interestsParam = new StringParameter(
+ ProfileSiteItemController.POSITION);
+ final TextArea interests = new TextArea(interestsParam);
+ interests.setCols(80);
+ interests.setRows(8);
+ add(interests);
+ }
+
+ @Override
+ public void init(final FormSectionEvent event) throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ data.put(ProfileSiteItemController.POSITION, profile.getInterests());
+
+ setVisible(state, true);
+ }
+
+ @Override
+ public void process(final FormSectionEvent event)
+ throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ if ((profile != null)
+ && getSaveCancelSection().getSaveButton().isSelected(state)) {
+
+ final ProfileSiteItemController controller = CdiUtil
+ .createCdiUtil()
+ .findBean(ProfileSiteItemController.class);
+
+ final Locale selectedLocale = SelectedLanguageUtil.selectedLocale(
+ state, selectedLangParam
+ );
+
+ controller.setInterests(
+ profile.getObjectId(),
+ (String) data.get(ProfileSiteItemController.POSITION),
+ selectedLocale
+ );
+ }
+
+ init(event);
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsStep.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsStep.java
new file mode 100644
index 000000000..d6fa011ea
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemInterestsStep.java
@@ -0,0 +1,81 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SimpleEditStep;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
+import com.arsdigita.globalization.GlobalizedMessage;
+import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
+
+import org.librecms.profilesite.ProfileSiteConstants;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemInterestsStep extends SimpleEditStep {
+
+ private String EDIT_POSITION_SHEET_NAME = "editInterests";
+
+ public ProfileSiteItemInterestsStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam
+ ) {
+ this(itemModel, parent, selectedLangParam, null);
+ }
+
+ public ProfileSiteItemInterestsStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam,
+ final String prefix
+ ) {
+ super(itemModel, parent, selectedLangParam, prefix);
+
+ final BasicItemForm editInterestsForm = new ProfileSiteItemInterestsForm(
+ itemModel, selectedLangParam
+ );
+ add(
+ EDIT_POSITION_SHEET_NAME,
+ new GlobalizedMessage(
+ "profile_site_site.ui.interests.edit",
+ ProfileSiteConstants.BUNDLE
+ ),
+ new WorkflowLockedComponentAccess(parent, itemModel),
+ editInterestsForm.getSaveCancelSection().getCancelButton()
+ );
+
+ setDisplayComponent(getProfileSiteItemInterestsSheet(
+ itemModel, selectedLangParam)
+ );
+ }
+
+ public static final Component getProfileSiteItemInterestsSheet(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ final DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(
+ itemModel, false, selectedLangParam
+ );
+
+ sheet.add(
+ new GlobalizedMessage(
+ "profile_site_item.ui.interests",
+ ProfileSiteConstants.BUNDLE
+ ),
+ ProfileSiteItemController.POSITION
+ );
+
+ return sheet;
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscForm.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscForm.java
new file mode 100644
index 000000000..040e95ee8
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscForm.java
@@ -0,0 +1,108 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.form.TextArea;
+import com.arsdigita.bebop.parameters.ParameterModel;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SelectedLanguageUtil;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.libreccm.cdi.utils.CdiUtil;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemMiscForm
+ extends BasicItemForm
+ implements FormProcessListener, FormInitListener {
+
+ private final StringParameter selectedLangParam;
+
+ public ProfileSiteItemMiscForm(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ super("ProfileSiteItemEditMisc", itemModel, selectedLangParam);
+ this.selectedLangParam = selectedLangParam;
+ }
+
+ @Override
+ public void addWidgets() {
+ add(
+ new Label(
+ new GlobalizedMessage(
+ "profile_site_item.ui.misc",
+ ProfileSiteConstants.BUNDLE
+ )
+ )
+ );
+ final ParameterModel miscParam = new StringParameter(
+ ProfileSiteItemController.POSITION);
+ final TextArea misc = new TextArea(miscParam);
+ misc.setCols(80);
+ misc.setRows(8);
+ add(misc);
+ }
+
+ @Override
+ public void init(final FormSectionEvent event) throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ data.put(ProfileSiteItemController.POSITION, profile.getMisc());
+
+ setVisible(state, true);
+ }
+
+ @Override
+ public void process(final FormSectionEvent event)
+ throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ if ((profile != null)
+ && getSaveCancelSection().getSaveButton().isSelected(state)) {
+
+ final ProfileSiteItemController controller = CdiUtil
+ .createCdiUtil()
+ .findBean(ProfileSiteItemController.class);
+
+ final Locale selectedLocale = SelectedLanguageUtil.selectedLocale(
+ state, selectedLangParam
+ );
+
+ controller.setMisc(
+ profile.getObjectId(),
+ (String) data.get(ProfileSiteItemController.POSITION),
+ selectedLocale
+ );
+ }
+
+ init(event);
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscStep.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscStep.java
new file mode 100644
index 000000000..fb12b9eb7
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemMiscStep.java
@@ -0,0 +1,81 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SimpleEditStep;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
+import com.arsdigita.globalization.GlobalizedMessage;
+import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
+
+import org.librecms.profilesite.ProfileSiteConstants;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemMiscStep extends SimpleEditStep {
+
+ private String EDIT_POSITION_SHEET_NAME = "editMisc";
+
+ public ProfileSiteItemMiscStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam
+ ) {
+ this(itemModel, parent, selectedLangParam, null);
+ }
+
+ public ProfileSiteItemMiscStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam,
+ final String prefix
+ ) {
+ super(itemModel, parent, selectedLangParam, prefix);
+
+ final BasicItemForm editMiscForm = new ProfileSiteItemMiscForm(
+ itemModel, selectedLangParam
+ );
+ add(
+ EDIT_POSITION_SHEET_NAME,
+ new GlobalizedMessage(
+ "profile_site_site.ui.misc.edit",
+ ProfileSiteConstants.BUNDLE
+ ),
+ new WorkflowLockedComponentAccess(parent, itemModel),
+ editMiscForm.getSaveCancelSection().getCancelButton()
+ );
+
+ setDisplayComponent(getProfileSiteItemMiscSheet(
+ itemModel, selectedLangParam)
+ );
+ }
+
+ public static final Component getProfileSiteItemMiscSheet(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ final DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(
+ itemModel, false, selectedLangParam
+ );
+
+ sheet.add(
+ new GlobalizedMessage(
+ "profile_site_item.ui.misc",
+ ProfileSiteConstants.BUNDLE
+ ),
+ ProfileSiteItemController.POSITION
+ );
+
+ return sheet;
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionForm.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionForm.java
new file mode 100644
index 000000000..548ed47ec
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionForm.java
@@ -0,0 +1,108 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.form.TextArea;
+import com.arsdigita.bebop.parameters.ParameterModel;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SelectedLanguageUtil;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.libreccm.cdi.utils.CdiUtil;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemPositionForm
+ extends BasicItemForm
+ implements FormProcessListener, FormInitListener {
+
+ private final StringParameter selectedLangParam;
+
+ public ProfileSiteItemPositionForm(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ super("ProfileSiteItemEditPosition", itemModel, selectedLangParam);
+ this.selectedLangParam = selectedLangParam;
+ }
+
+ @Override
+ public void addWidgets() {
+ add(
+ new Label(
+ new GlobalizedMessage(
+ "profile_site_item.ui.position",
+ ProfileSiteConstants.BUNDLE
+ )
+ )
+ );
+ final ParameterModel positionParam = new StringParameter(
+ ProfileSiteItemController.POSITION);
+ final TextArea position = new TextArea(positionParam);
+ position.setCols(80);
+ position.setRows(8);
+ add(position);
+ }
+
+ @Override
+ public void init(final FormSectionEvent event) throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ data.put(ProfileSiteItemController.POSITION, profile.getPosition());
+
+ setVisible(state, true);
+ }
+
+ @Override
+ public void process(final FormSectionEvent event)
+ throws FormProcessException {
+ final PageState state = event.getPageState();
+ final FormData data = event.getFormData();
+ final ProfileSiteItem profile
+ = (ProfileSiteItem) getItemSelectionModel()
+ .getSelectedItem(state);
+
+ if ((profile != null)
+ && getSaveCancelSection().getSaveButton().isSelected(state)) {
+
+ final ProfileSiteItemController controller = CdiUtil
+ .createCdiUtil()
+ .findBean(ProfileSiteItemController.class);
+
+ final Locale selectedLocale = SelectedLanguageUtil.selectedLocale(
+ state, selectedLangParam
+ );
+
+ controller.setPosition(
+ profile.getObjectId(),
+ (String) data.get(ProfileSiteItemController.POSITION),
+ selectedLocale
+ );
+ }
+
+ init(event);
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionStep.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionStep.java
new file mode 100644
index 000000000..6d74d393b
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPositionStep.java
@@ -0,0 +1,81 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.authoring.BasicItemForm;
+import com.arsdigita.cms.ui.authoring.SimpleEditStep;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
+import com.arsdigita.globalization.GlobalizedMessage;
+import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
+
+import org.librecms.profilesite.ProfileSiteConstants;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemPositionStep extends SimpleEditStep {
+
+ private String EDIT_POSITION_SHEET_NAME = "editPosition";
+
+ public ProfileSiteItemPositionStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam
+ ) {
+ this(itemModel, parent, selectedLangParam, null);
+ }
+
+ public ProfileSiteItemPositionStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam,
+ final String prefix
+ ) {
+ super(itemModel, parent, selectedLangParam, prefix);
+
+ final BasicItemForm editPositionForm = new ProfileSiteItemPositionForm(
+ itemModel, selectedLangParam
+ );
+ add(
+ EDIT_POSITION_SHEET_NAME,
+ new GlobalizedMessage(
+ "profile_site_site.ui.position.edit",
+ ProfileSiteConstants.BUNDLE
+ ),
+ new WorkflowLockedComponentAccess(parent, itemModel),
+ editPositionForm.getSaveCancelSection().getCancelButton()
+ );
+
+ setDisplayComponent(getProfileSiteItemPositionSheet(
+ itemModel, selectedLangParam)
+ );
+ }
+
+ public static final Component getProfileSiteItemPositionSheet(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ final DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(
+ itemModel, false, selectedLangParam
+ );
+
+ sheet.add(
+ new GlobalizedMessage(
+ "profile_site_item.ui.position",
+ ProfileSiteConstants.BUNDLE
+ ),
+ ProfileSiteItemController.POSITION
+ );
+
+ return sheet;
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertiesStep.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertiesStep.java
new file mode 100644
index 000000000..3d27d2359
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertiesStep.java
@@ -0,0 +1,116 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.SegmentedPanel;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+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.globalization.GlobalizedMessage;
+import com.arsdigita.toolbox.ui.DomainObjectPropertySheet;
+
+import org.librecms.assets.Person;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemPropertiesStep extends SimpleEditStep {
+
+ public static final String EDIT_SHEET_NAME = "editProfileSiteItem";
+
+ public ProfileSiteItemPropertiesStep(
+ final ItemSelectionModel itemModel,
+ final AuthoringKitWizard parent,
+ final StringParameter selectedLangParam
+ ) {
+ super(itemModel, parent, selectedLangParam);
+
+ setDefaultEditKey(EDIT_SHEET_NAME);
+
+ final SimpleEditStep basicProperties = new SimpleEditStep(
+ itemModel, parent, selectedLangParam, EDIT_SHEET_NAME
+ );
+ final BasicPageForm editBasicSheet = new ProfileSiteItemPropertyForm(
+ itemModel, this, selectedLangParam
+ );
+
+ basicProperties.add(
+ EDIT_SHEET_NAME,
+ new GlobalizedMessage(
+ ProfileSiteConstants.BUNDLE,
+ "profile_site.ui.edit_basic_properties"
+ ),
+ new WorkflowLockedComponentAccess(editBasicSheet, itemModel),
+ editBasicSheet.getSaveCancelSection().getCancelButton()
+ );
+
+ basicProperties.setDisplayComponent(
+ getProfileSiteItemPropertiesSheet(itemModel, selectedLangParam)
+ );
+
+ final SegmentedPanel segmentedPanel = new SegmentedPanel();
+ segmentedPanel.addSegment(
+ new Label(
+ new GlobalizedMessage(
+ ProfileSiteConstants.BUNDLE,
+ "profile_site.ui.basic_properties"
+ )
+ ),
+ basicProperties
+ );
+
+ setDisplayComponent(segmentedPanel);
+ }
+
+ public static Component getProfileSiteItemPropertiesSheet(
+ final ItemSelectionModel itemModel,
+ final StringParameter selectedLangParam
+ ) {
+ final DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(
+ itemModel, false, selectedLangParam
+ );
+
+ sheet.add(
+ new GlobalizedMessage(
+ ProfileSiteConstants.BUNDLE, "profile_site.ui.OWNER"
+ ),
+ ProfileSiteItemController.OWNER,
+ new OwnerFormatter()
+ );
+
+ return sheet;
+ }
+
+ private static class OwnerFormatter
+ implements DomainObjectPropertySheet.AttributeFormatter {
+
+ @Override
+ public String format(
+ final Object obj, final String attribute, final PageState state
+ ) {
+ final ProfileSiteItem profileSiteItem = (ProfileSiteItem) obj;
+
+ final Person owner = profileSiteItem.getOwner();
+
+ if (owner == null) {
+ return "";
+ } else {
+ return owner.getDisplayName();
+ }
+ }
+
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertyForm.java b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertyForm.java
new file mode 100644
index 000000000..949eca678
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/com/arsdigita/cms/contenttypes/ui/ProfileSiteItemPropertyForm.java
@@ -0,0 +1,104 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.arsdigita.cms.contenttypes.ui;
+
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.event.FormValidationListener;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.assets.AssetSearchWidget;
+import com.arsdigita.cms.ui.authoring.BasicPageForm;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.libreccm.cdi.utils.CdiUtil;
+import org.librecms.assets.Person;
+import org.librecms.profilesite.ProfileSiteConstants;
+import org.librecms.profilesite.ProfileSiteItem;
+
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class ProfileSiteItemPropertyForm
+ extends BasicPageForm
+ implements FormInitListener, FormProcessListener, FormValidationListener {
+
+ public static final String ID = "PublicPersonalProfile_edit";
+
+ private static final String OWNER_SEARCH = "ownerSearch";
+
+ private final ItemSelectionModel itemModel;
+
+ public ProfileSiteItemPropertyForm(
+ final ItemSelectionModel itemModel,
+ final ProfileSiteItemPropertiesStep step,
+ final StringParameter selectedLangParam
+ ) {
+ super(ID, itemModel, selectedLangParam);
+ this.itemModel = itemModel;
+ addValidationListener(this);
+ }
+
+ @Override
+ public void addWidgets() {
+ super.addWidgets();
+
+ final AssetSearchWidget ownerSearch = new AssetSearchWidget(
+ OWNER_SEARCH, Person.class
+ );
+ add(ownerSearch);
+ }
+
+ @Override
+ public void init(final FormSectionEvent event) throws FormProcessException {
+ final FormData formData = event.getFormData();
+ final ProfileSiteItem profileSiteItem = (ProfileSiteItem) super
+ .initBasicWidgets(event);
+ formData.put(OWNER_SEARCH, profileSiteItem.getOwner());
+ }
+
+ @Override
+ public void validate(final FormSectionEvent event)
+ throws FormProcessException {
+ super.validate(event);
+
+ final FormData formData = event.getFormData();
+ if (!formData.containsKey(OWNER_SEARCH)
+ || formData.get(OWNER_SEARCH) == null) {
+ formData.addError(
+ new GlobalizedMessage(
+ "profile_site.owner.not_selected",
+ ProfileSiteConstants.BUNDLE
+ )
+ );
+ }
+ }
+
+ @Override
+ public void process(final FormSectionEvent event)
+ throws FormProcessException {
+
+ final ProfileSiteItem profileSiteItem = (ProfileSiteItem) super
+ .processBasicWidgets(event);
+ final FormData formData = event.getFormData();
+ final Person owner = (Person) formData.get(OWNER_SEARCH);
+
+ final ProfileSiteItemController controller = CdiUtil
+ .createCdiUtil()
+ .findBean(ProfileSiteItemController.class);
+ controller.setOwner(profileSiteItem.getObjectId(), owner.getObjectId());
+
+ init(event);
+ }
+
+
+
+}
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSite.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSite.java
new file mode 100644
index 000000000..a573663ac
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSite.java
@@ -0,0 +1,50 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.librecms.profilesite;
+
+import org.libreccm.modules.CcmModule;
+import org.libreccm.modules.InitEvent;
+import org.libreccm.modules.InstallEvent;
+import org.libreccm.modules.RequiredModule;
+import org.libreccm.modules.ShutdownEvent;
+import org.libreccm.modules.UnInstallEvent;
+import org.librecms.contenttypes.ContentTypes;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@org.libreccm.modules.Module(
+ requiredModules = {
+ @RequiredModule(module = org.librecms.Cms.class)
+ }
+)
+@ContentTypes({
+ ProfileSiteItem.class
+})
+public class ProfileSite implements CcmModule {
+
+ @Override
+ public void install(final InstallEvent event) {
+ //Nothing
+ }
+
+ @Override
+ public void init(final InitEvent event) {
+ //Nothing
+ }
+
+ @Override
+ public void shutdown(final ShutdownEvent event) {
+ //Nothing
+ }
+
+ @Override
+ public void uninstall(final UnInstallEvent event) {
+ //Nothing
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteConstants.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteConstants.java
index 695e2e2e2..1942ac136 100644
--- a/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteConstants.java
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteConstants.java
@@ -11,6 +11,8 @@ package org.librecms.profilesite;
*/
public class ProfileSiteConstants {
+ public static final String BUNDLE = "org.librecms.profilesite.ProfileSiteResources";
+
public static final String DB_SCHEMA = "cms_profile";
private ProfileSiteConstants() {
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteItem.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteItem.java
index 9bba81913..698eae250 100644
--- a/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteItem.java
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/ProfileSiteItem.java
@@ -5,17 +5,26 @@
*/
package org.librecms.profilesite;
-import org.hibernate.annotations.Type;
+import com.arsdigita.cms.contenttypes.ui.ProfileSiteItemCreate;
+import com.arsdigita.cms.contenttypes.ui.ProfileSiteItemInterestsStep;
+import com.arsdigita.cms.contenttypes.ui.ProfileSiteItemMiscStep;
+import com.arsdigita.cms.contenttypes.ui.ProfileSiteItemPositionStep;
+import com.arsdigita.cms.contenttypes.ui.ProfileSiteItemPropertiesStep;
+
+import org.libreccm.l10n.LocalizedString;
import org.librecms.assets.Person;
import org.librecms.contentsection.ContentItem;
+import org.librecms.contenttypes.AuthoringKit;
+import org.librecms.contenttypes.AuthoringStep;
+import org.librecms.contenttypes.ContentTypeDescription;
import java.util.Objects;
-import javax.persistence.Basic;
-import javax.persistence.Column;
+import javax.persistence.AssociationOverride;
+import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
+import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@@ -27,6 +36,47 @@ import static org.librecms.profilesite.ProfileSiteConstants.*;
*/
@Entity
@Table(name = "PROFILE_SITES", schema = DB_SCHEMA)
+@ContentTypeDescription(
+ labelBundle = "org.librecms.profilesite.ProfileSiteItem",
+ descriptionBundle = "org.librecms.profilesite.ProfileSiteItem"
+)
+@AuthoringKit(
+ createComponent = ProfileSiteItemCreate.class,
+ steps = {
+ @AuthoringStep(
+ component = ProfileSiteItemPropertiesStep.class,
+ labelBundle = ProfileSiteConstants.BUNDLE,
+ labelKey = "profile_site_item.basic_properties.label",
+ descriptionBundle = ProfileSiteConstants.BUNDLE,
+ descriptionKey = "profile_site_item.basic_properties.description",
+ order = 1
+ ),
+ @AuthoringStep(
+ component = ProfileSiteItemPositionStep.class,
+ labelBundle = ProfileSiteConstants.BUNDLE,
+ labelKey = "profile_site_item.position.label",
+ descriptionBundle = ProfileSiteConstants.BUNDLE,
+ descriptionKey = "profile_site_item.position.description",
+ order = 2
+ ),
+ @AuthoringStep(
+ component = ProfileSiteItemInterestsStep.class,
+ labelBundle = ProfileSiteConstants.BUNDLE,
+ labelKey = "profile_site_item.interests.label",
+ descriptionBundle = ProfileSiteConstants.BUNDLE,
+ descriptionKey = "profile_site_item.interests.description",
+ order = 3
+ ),
+ @AuthoringStep(
+ component = ProfileSiteItemMiscStep.class,
+ labelBundle = ProfileSiteConstants.BUNDLE,
+ labelKey = "profile_site_item.misc.label",
+ descriptionBundle = ProfileSiteConstants.BUNDLE,
+ descriptionKey = "profile_site_item.misc.description",
+ order = 4
+ )
+ }
+)
public class ProfileSiteItem extends ContentItem {
private static final long serialVersionUID = 1L;
@@ -35,23 +85,50 @@ public class ProfileSiteItem extends ContentItem {
@JoinColumn(name = "OWNER_ID")
private Person owner;
- @Column(name = "POSITION")
- @Basic
- @Lob
- @Type(type = "org.hibernate.type.TextType")
- private String position;
+ @Embedded
+ @AssociationOverride(
+ name = "values",
+ joinTable = @JoinTable(
+ name = "PROFILE_SITE_ITEMS_POSITION",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "PROFILE_SITE_ITEM_ID")
+ }
+ )
+ )
+ private LocalizedString position;
- @Column(name = "INTERESTS")
- @Basic
- @Lob
- @Type(type = "org.hibernate.type.TextType")
- private String interests;
+ @Embedded
+ @AssociationOverride(
+ name = "values",
+ joinTable = @JoinTable(
+ name = "PROFILE_SITE_ITEMS_INTERESTS",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "PROFILE_SITE_ITEM_ID")
+ }
+ )
+ )
+ private LocalizedString interests;
- @Column(name = "MISC")
- @Basic
- @Lob
- @Type(type = "org.hibernate.type.TextType")
- private String misc;
+ @Embedded
+ @AssociationOverride(
+ name = "values",
+ joinTable = @JoinTable(
+ name = "PROFILE_SITE_ITEMS_MISC",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "PROFILE_SITE_ITEM_ID")
+ }
+ )
+ )
+ private LocalizedString misc;
+
+ public ProfileSiteItem() {
+ position = new LocalizedString();
+ interests = new LocalizedString();
+ misc = new LocalizedString();
+ }
public Person getOwner() {
return owner;
@@ -61,27 +138,27 @@ public class ProfileSiteItem extends ContentItem {
this.owner = owner;
}
- public String getPosition() {
+ public LocalizedString getPosition() {
return position;
}
- public void setPosition(final String position) {
+ protected void setPosition(final LocalizedString position) {
this.position = position;
}
- public String getInterests() {
+ public LocalizedString getInterests() {
return interests;
}
- public void setInterests(final String interests) {
+ protected void setInterests(final LocalizedString interests) {
this.interests = interests;
}
- public String getMisc() {
+ public LocalizedString getMisc() {
return misc;
}
- public void setMisc(final String misc) {
+ protected void setMisc(final LocalizedString misc) {
this.misc = misc;
}
@@ -146,9 +223,9 @@ public class ProfileSiteItem extends ContentItem {
+ "interests = \"%s\", "
+ "misc = \"%s\"%s",
Objects.toString(owner),
- position,
- interests,
- misc,
+ Objects.toString(position),
+ Objects.toString(interests),
+ Objects.toString(misc),
data
)
);
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponent.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponent.java
new file mode 100644
index 000000000..a2f0a2276
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponent.java
@@ -0,0 +1,26 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.librecms.profilesite.pagemodel;
+
+import org.libreccm.pagemodel.ComponentModel;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import static org.librecms.profilesite.ProfileSiteConstants.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "PROFILE_SITE_COMPONENTS", schema = DB_SCHEMA)
+public class ProfileSiteComponent extends ComponentModel {
+
+ private static final long serialVersionUID = 1L;
+
+
+}
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponentRenderer.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponentRenderer.java
new file mode 100644
index 000000000..2b25c6c1b
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteComponentRenderer.java
@@ -0,0 +1,270 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.librecms.profilesite.pagemodel;
+
+import com.arsdigita.kernel.KernelConfig;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.libreccm.categorization.Category;
+import org.libreccm.categorization.CategoryManager;
+import org.libreccm.categorization.CategoryRepository;
+import org.libreccm.configuration.ConfigurationManager;
+import org.libreccm.core.CcmObject;
+import org.libreccm.pagemodel.ComponentRenderer;
+import org.libreccm.pagemodel.RendersComponent;
+import org.libreccm.security.PermissionChecker;
+import org.librecms.assets.Person;
+import org.librecms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItemL10NManager;
+import org.librecms.contentsection.ContentItemManager;
+import org.librecms.contentsection.ContentItemVersion;
+import org.librecms.contentsection.privileges.ItemPrivileges;
+import org.librecms.pagemodel.assets.AbstractAssetRenderer;
+import org.librecms.pagemodel.assets.AssetRenderers;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import static org.librecms.pages.PagesConstants.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@RendersComponent(componentModel = ProfileSiteComponent.class)
+public class ProfileSiteComponentRenderer
+ implements ComponentRenderer {
+
+ private static final Logger LOGGER = LogManager.getLogger(
+ ProfileSiteComponentRenderer.class
+ );
+
+ @Inject
+ private AssetRenderers assetRenderers;
+
+ @Inject
+ private CategoryRepository categoryRepo;
+
+ @Inject
+ private CategoryManager categoryManager;
+
+ @Inject
+ private ConfigurationManager confManager;
+
+ @Inject
+ private ContentItemL10NManager iteml10nManager;
+
+ @Inject
+ private Instance contentRenderers;
+
+ @Inject
+ private ContentItemManager itemManager;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ @Override
+ public Map renderComponent(
+ final ProfileSiteComponent componentModel,
+ final Map parameters
+ ) {
+ Objects.requireNonNull(componentModel);
+ Objects.requireNonNull(parameters);
+
+ if (!parameters.containsKey(PARAMETER_CATEGORY)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "The parameters map passed to this component does "
+ + "not include the parameter \"%s\"",
+ PARAMETER_CATEGORY
+ )
+ );
+ }
+
+ if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "The parameters map passed to this ProfileSiteComponent "
+ + "component contains the parameter \"category\", but "
+ + "parameter is not of type \"%s\" but of type \"%s\".",
+ Category.class.getName(),
+ parameters.get(PARAMETER_CATEGORY).getClass().getName()
+ )
+ );
+ }
+
+ final Category category = categoryRepo
+ .findById(
+ ((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId()
+ )
+ .orElseThrow(
+ () -> new IllegalArgumentException(
+ String.format(
+ "No category with ID %d in the database.",
+ ((CcmObject) parameters.get(PARAMETER_CATEGORY))
+ .getObjectId()
+ )
+ )
+ );
+
+ final Optional indexObj = categoryManager
+ .getIndexObject(category)
+ .stream()
+ .filter(object -> object instanceof ContentItem)
+ .filter(item -> {
+ return ((ContentItem) item)
+ .getVersion() == ContentItemVersion.LIVE;
+ })
+ .findFirst();
+
+ if (indexObj.isPresent()) {
+
+ if (!(indexObj.get() instanceof ProfileSiteItem)) {
+ LOGGER.debug(
+ "The index item of the category {} is not an item of "
+ + "the class",
+ ProfileSiteItem.class.getName()
+ );
+ return Collections.emptyMap();
+ }
+
+ final ProfileSiteItem profileSiteItem = (ProfileSiteItem) indexObj
+ .get();
+
+ if (Boolean.TRUE.equals(parameters.get("showDraft"))) {
+ final ProfileSiteItem draftItem = itemManager
+ .getDraftVersion(profileSiteItem, profileSiteItem.getClass());
+
+ if (permissionChecker.isPermitted(
+ ItemPrivileges.PREVIEW, draftItem
+ )) {
+ final Map result = generateItem(
+ componentModel, parameters, draftItem
+ );
+ result.put("showDraft", Boolean.TRUE);
+
+ return result;
+ } else {
+ throw new WebApplicationException(
+ "You are not permitted to view the draft version of "
+ + "this profile site.",
+ Response.Status.UNAUTHORIZED
+ );
+ }
+ } else {
+ final ProfileSiteItem liveItem = itemManager
+ .getLiveVersion(profileSiteItem, profileSiteItem.getClass())
+ .orElseThrow(
+ () -> new NotFoundException(
+ "This content item does not have a live version."
+ )
+ );
+
+ if (permissionChecker.isPermitted(
+ ItemPrivileges.VIEW_PUBLISHED, liveItem
+ )) {
+ return generateItem(
+ componentModel, parameters, liveItem
+ );
+ } else {
+ throw new WebApplicationException(
+ "You are not permitted to view the live version of "
+ + "this profile site.",
+ Response.Status.UNAUTHORIZED);
+ }
+ }
+ } else {
+ LOGGER.debug("The category {} does not have a index item.",
+ Objects.toString(category));
+ return Collections.emptyMap();
+ }
+ }
+
+ protected Map generateItem(
+ final ProfileSiteComponent componentModel,
+ final Map parameters,
+ final ProfileSiteItem profileSiteItem
+ ) {
+ final Category category = (Category) parameters.get(PARAMETER_CATEGORY);
+ final String categoryName = category.getName();
+
+ final Optional result = contentRenderers
+ .stream()
+ .filter(renderer -> categoryName.equals(renderer.getCategoryName()))
+ .findAny();
+
+ if (result.isPresent()) {
+ return result.get().renderContent(
+ componentModel, parameters, profileSiteItem
+ );
+ } else {
+ return renderProfileSiteIndexPage(parameters, profileSiteItem);
+ }
+ }
+
+ private Map renderProfileSiteIndexPage(
+ final Map parameters,
+ final ProfileSiteItem profileSiteItem
+ ) {
+ final Locale language;
+ if (parameters.containsKey("language")) {
+ language = new Locale((String) parameters
+ .get(PARAMETER_LANGUAGE));
+ } else {
+ final KernelConfig kernelConfig = confManager
+ .findConfiguration(KernelConfig.class);
+ language = kernelConfig.getDefaultLocale();
+ }
+
+ if (iteml10nManager.hasLanguage(profileSiteItem, language)) {
+
+ final Map result = new HashMap<>();
+
+ result.put(
+ "owner", renderOwner(profileSiteItem.getOwner(), language)
+ );
+ result.put(
+ "position", profileSiteItem.getPosition().getValue(language)
+ );
+ result.put(
+ "interests", profileSiteItem.getInterests().getValue(language)
+ );
+ result.put(
+ "misc", profileSiteItem.getMisc().getValue(language)
+ );
+
+ return result;
+ } else {
+ throw new NotFoundException(
+ "Requested language is not available.");
+ }
+ }
+
+ private Map renderOwner(
+ final Person owner, final Locale language
+ ) {
+ final AbstractAssetRenderer renderer = assetRenderers.findRenderer(
+ owner.getClass()
+ );
+
+ return renderer.render(owner, language);
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteContentRenderer.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteContentRenderer.java
new file mode 100644
index 000000000..1b79701a1
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/ProfileSiteContentRenderer.java
@@ -0,0 +1,41 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.librecms.profilesite.pagemodel;
+
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Map;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public interface ProfileSiteContentRenderer {
+
+ /**
+ * Provides the category name for which this renderer is responsible.
+ *
+ * @return The category name for which this renderer is responsible.
+ */
+ String getCategoryName();
+
+ /**
+ * Renders special content for a profile site depending on the current
+ * category.
+ *
+ * @param componentModel
+ * @param parameters
+ * @param profileSiteItem
+ *
+ * @return
+ */
+ Map renderContent(
+ ProfileSiteComponent componentModel,
+ Map parameters,
+ ProfileSiteItem profileSiteItem
+ );
+
+}
diff --git a/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/contentitem/ProfileSiteItemRenderer.java b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/contentitem/ProfileSiteItemRenderer.java
new file mode 100644
index 000000000..619b232fe
--- /dev/null
+++ b/ccm-cms-profile/src/main/java/org/librecms/profilesite/pagemodel/contentitem/ProfileSiteItemRenderer.java
@@ -0,0 +1,54 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.librecms.profilesite.pagemodel.contentitem;
+
+import org.librecms.contentsection.ContentItem;
+import org.librecms.pagemodel.assets.AssetRenderers;
+import org.librecms.pagemodel.contentitems.AbstractContentItemRenderer;
+import org.librecms.pagemodel.contentitems.ContentItemRenderer;
+import org.librecms.profilesite.ProfileSiteItem;
+
+import java.util.Locale;
+import java.util.Map;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@ContentItemRenderer(renders = ProfileSiteItem.class)
+@RequestScoped
+public class ProfileSiteItemRenderer extends AbstractContentItemRenderer {
+
+ private static final long serialVersionUID = 1L;
+
+
+ @Inject
+ private AssetRenderers assetRenderers;
+
+ @Override
+ protected void renderItem(
+ final ContentItem item,
+ final Locale language,
+ final Map result
+ ) {
+ // Nothing
+// final ProfileSiteItem profileSiteItem;
+// if (item instanceof ProfileSiteItem) {
+// profileSiteItem = (ProfileSiteItem) item;
+// } else {
+// return;
+// }
+ }
+
+ @Override
+ protected AssetRenderers getAssetRenderers() {
+ return assetRenderers;
+ }
+
+}
diff --git a/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem.properties b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem.properties
new file mode 100644
index 000000000..8af3a7be1
--- /dev/null
+++ b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem.properties
@@ -0,0 +1,2 @@
+label=Profile Site
+description=Item for creating a profile site for a person.
diff --git a/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem_de.properties b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem_de.properties
new file mode 100644
index 000000000..89184cbce
--- /dev/null
+++ b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteItem_de.properties
@@ -0,0 +1,2 @@
+label=Profil Seite
+description=Eine Profile Seite f\u00fcr eine Person
diff --git a/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources.properties b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources.properties
new file mode 100644
index 000000000..5f41d3073
--- /dev/null
+++ b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources.properties
@@ -0,0 +1,10 @@
+profile_site.owner.label=Profile of
+profile_site.owner.not_selected=Profile owner is required
+profile_site_item.basic_properties.label=Basic Properties
+profile_site_item.basic_properties.description=Basic Properties
+profile_site_item.position.label=Position
+profile_site_item.position.description=Position
+profile_site_item.interests.label=Interests
+profile_site_item.interests.description=Interests
+profile_site_item.misc.label=Misc
+profile_site_item.misc.description=Misc
diff --git a/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources_de.properties b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources_de.properties
new file mode 100644
index 000000000..58cb0cab3
--- /dev/null
+++ b/ccm-cms-profile/src/main/resources/org/librecms/profilesite/ProfileSiteResources_de.properties
@@ -0,0 +1,10 @@
+profile_site.owner.label=Profil von
+profile_site.owner.not_selected=Bitte den Eigent\u00fcmer des Profils angeben
+profile_site_item.basic_properties.label=Basis Eigenschaften
+profile_site_item.basic_properties.description=Basis Eigenschaften
+profile_site_item.position.label=Position
+profile_site_item.position.description=Position
+profile_site_item.interests.label=Interessen
+profile_site_item.interests.description=Interessen
+profile_site_item.misc.label=Verschiedenes
+profile_site_item.misc.description=Verschiedeses