/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal.portlets.portletadmin; import java.io.Serializable; import java.text.ParseException; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import org.apache.commons.collections.map.LazyMap; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apereo.portal.layout.dlm.remoting.JsonEntityBean; import org.apereo.portal.portlet.om.IPortletDefinition; import org.apereo.portal.portlet.om.IPortletDefinitionParameter; import org.apereo.portal.portlet.om.IPortletPreference; import org.apereo.portal.portlet.om.PortletLifecycleState; import org.apereo.portal.portletpublishing.xml.MultiValuedPreferenceInputType; import org.apereo.portal.portletpublishing.xml.Parameter; import org.apereo.portal.portletpublishing.xml.ParameterInputType; import org.apereo.portal.portletpublishing.xml.PortletPublishingDefinition; import org.apereo.portal.portletpublishing.xml.Preference; import org.apereo.portal.portletpublishing.xml.PreferenceInputType; import org.apereo.portal.portletpublishing.xml.SingleValuedPreferenceInputType; import org.apereo.portal.portletpublishing.xml.Step; import org.apereo.portal.portlets.Attribute; import org.apereo.portal.portlets.AttributeFactory; import org.apereo.portal.portlets.BooleanAttribute; import org.apereo.portal.portlets.BooleanAttributeFactory; import org.apereo.portal.portlets.StringListAttribute; import org.apereo.portal.portlets.StringListAttributeFactory; import org.apereo.portal.xml.PortletDescriptor; public class PortletDefinitionForm implements Serializable { private static final String FRAMEWORK_PORTLET_URL = "/uPortal"; private static final FastDateFormat dateFormat = FastDateFormat.getInstance("M/d/yyyy"); private static final long serialVersionUID = 892741367149099649L; protected final transient Log log = LogFactory.getLog(getClass()); /** Main portlet fields */ private String id = null; private String fname = ""; private String name = ""; private String description = ""; private String title = ""; private String applicationId = ""; private String portletName = ""; private boolean framework = false; private int timeout = 5000; private int typeId; /** Lifecycle information */ private PortletLifecycleState lifecycleState = PortletLifecycleState.CREATED; private Date publishDate; private int publishHour = 12; private int publishMinute = 0; private int publishAmPm = 0; private Date expirationDate; private int expirationHour = 12; private int expirationMinute = 0; private int expirationAmPm = 0; /** Portlet controls */ private boolean editable; private boolean hasHelp; private boolean hasAbout; private boolean configurable; /** Principals and categories */ private SortedSet<JsonEntityBean> principals = new TreeSet<>(); private SortedSet<JsonEntityBean> categories = new TreeSet<>(); private Set<String> permissions = new HashSet<>(); /** Parameters and preferences */ @SuppressWarnings("unchecked") private Map<String, Attribute> parameters = LazyMap.decorate(new HashMap<String, Attribute>(), new AttributeFactory()); @SuppressWarnings("unchecked") private Map<String, StringListAttribute> portletPreferences = LazyMap.decorate( new HashMap<String, StringListAttribute>(), new StringListAttributeFactory()); @SuppressWarnings("unchecked") private Map<String, BooleanAttribute> portletPreferenceReadOnly = LazyMap.decorate( new HashMap<String, BooleanAttribute>(), new BooleanAttributeFactory()); /** Default constructor */ public PortletDefinitionForm() {} /** * Construct a new PortletDefinitionForm from a PortletDefinition * * @param def */ public PortletDefinitionForm(IPortletDefinition def) { this.setId(def.getPortletDefinitionId().getStringId()); this.setFname(def.getFName()); this.setName(def.getName()); this.setDescription(def.getDescription()); this.setTitle(def.getTitle()); this.setTimeout(def.getTimeout()); this.setTypeId(def.getType().getId()); this.setApplicationId(def.getPortletDescriptorKey().getWebAppName()); this.setPortletName(def.getPortletDescriptorKey().getPortletName()); this.setFramework(def.getPortletDescriptorKey().isFrameworkPortlet()); if (def.getParameter(IPortletDefinition.EDITABLE_PARAM) != null) { this.setEditable( Boolean.parseBoolean( def.getParameter(IPortletDefinition.EDITABLE_PARAM).getValue())); } if (def.getParameter(IPortletDefinition.CONFIGURABLE_PARAM) != null) { this.setConfigurable( Boolean.parseBoolean( def.getParameter(IPortletDefinition.CONFIGURABLE_PARAM).getValue())); } if (def.getParameter(IPortletDefinition.HAS_HELP_PARAM) != null) { this.setHasHelp( Boolean.parseBoolean( def.getParameter(IPortletDefinition.HAS_HELP_PARAM).getValue())); } if (def.getParameter(IPortletDefinition.HAS_ABOUT_PARAM) != null) { this.setHasAbout( Boolean.parseBoolean( def.getParameter(IPortletDefinition.HAS_ABOUT_PARAM).getValue())); } this.setLifecycleState(def.getLifecycleState()); if (def.getLifecycleState().equals(PortletLifecycleState.APPROVED)) { this.setPublishDateTime(def.getPublishDate()); } if (def.getLifecycleState().equals(PortletLifecycleState.PUBLISHED)) { this.setExpirationDateTime(def.getExpirationDate()); } for (IPortletDefinitionParameter param : def.getParameters()) { if (param.getName().startsWith("PORTLET.")) { this.portletPreferences.put( param.getName(), new StringListAttribute(new String[] {param.getValue()})); } else { this.parameters.put(param.getName(), new Attribute(param.getValue())); } } for (IPortletPreference pref : def.getPortletPreferences()) { this.portletPreferences.put(pref.getName(), new StringListAttribute(pref.getValues())); this.portletPreferenceReadOnly.put( pref.getName(), new BooleanAttribute(pref.isReadOnly())); } } /** * Indicates whether this portlet has been previously published. * * @return */ public boolean isNew() { return id == null || id.equals("-1"); } /** * Sets the Java class name and parameter defaults based on the PortletPublishingDefinition. * * @param cpd */ public void setChannelPublishingDefinition(PortletPublishingDefinition cpd) { // Set appName/portletName if a descriptor is present. If a framework // portlet, the applicationId is /uPortal. if (cpd.getPortletDescriptor() != null) { final PortletDescriptor pDesc = cpd.getPortletDescriptor(); // PortletDescriptor is a class generated from XSD. The value of // isIsFramework() will commonly be null. final boolean isFramework = pDesc.isIsFramework() != null ? pDesc.isIsFramework() : false; applicationId = isFramework ? FRAMEWORK_PORTLET_URL : pDesc.getWebAppName(); portletName = pDesc.getPortletName(); } // set default values for all portlet parameters for (Step step : cpd.getSteps()) { if (step.getParameters() != null) { for (Parameter param : step.getParameters()) { // if this parameter doesn't currently have a value, check // for a default in the CPD Attribute attribute = this.parameters.get(param.getName()); if (attribute == null || attribute.getValue() == null || attribute.getValue().trim().equals("")) { // use the default value if one exists ParameterInputType input = param.getParameterInput().getValue(); if (input != null) { this.parameters.put(param.getName(), new Attribute(input.getDefault())); } } } } if (step.getPreferences() != null) { for (Preference pref : step.getPreferences()) { // if this parameter doesn't currently have a value, check // for a default in the CPD if (!this.portletPreferences.containsKey(pref.getName()) || this.portletPreferences.get(pref.getName()).getValue().size() == 0 || (this.portletPreferences.get(pref.getName()).getValue().size() == 1 && this.portletPreferences .get(pref.getName()) .getValue() .get(0) .trim() .equals(""))) { if (!this.portletPreferences.containsKey(pref.getName())) { this.portletPreferences.put(pref.getName(), new StringListAttribute()); } // use the default value if one exists PreferenceInputType input = pref.getPreferenceInput().getValue(); if (input instanceof SingleValuedPreferenceInputType) { SingleValuedPreferenceInputType singleValued = (SingleValuedPreferenceInputType) input; if (singleValued.getDefault() != null) { this.portletPreferences .get(pref.getName()) .getValue() .add(singleValued.getDefault()); } } else if (input instanceof MultiValuedPreferenceInputType) { MultiValuedPreferenceInputType multiValued = (MultiValuedPreferenceInputType) input; if (multiValued.getDefaults() != null) { this.portletPreferences .get(pref.getName()) .getValue() .addAll(multiValued.getDefaults()); } } } } } } } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFname() { return fname; } public void setFname(String name) { fname = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public boolean isPortlet() { return true; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public int getTypeId() { return typeId; } public void setTypeId(int typeId) { this.typeId = typeId; } public String getApplicationId() { return applicationId; } public void setApplicationId(String applicationId) { // Be careful not to pass on extra whitespace this.applicationId = StringUtils.isNotBlank(applicationId) ? applicationId.trim() : applicationId; } public String getPortletName() { return portletName; } public void setPortletName(String portletName) { // Be careful not to pass on extra whitespace this.portletName = portletName.trim(); } public boolean isFramework() { return framework; } public void setFramework(boolean framework) { this.framework = framework; } public void setLifecycleState(PortletLifecycleState lifecycleState) { this.lifecycleState = lifecycleState; } public void setLifecycleState(String lifecycleState) { for (PortletLifecycleState state : PortletLifecycleState.values()) { if (state.toString().equals(lifecycleState)) { this.lifecycleState = state; break; } } } public PortletLifecycleState getLifecycleState() { return lifecycleState; } public Date getPublishDate() { return publishDate; } public void setPublishDate(Date publishDate) { this.publishDate = publishDate; } public Date getExpirationDate() { return expirationDate; } public void setExpirationDate(Date expirationDate) { this.expirationDate = expirationDate; } public boolean isEditable() { return editable; } public void setEditable(boolean editable) { this.editable = editable; } public boolean isConfigurable() { return configurable; } public void setConfigurable(boolean configurable) { this.configurable = configurable; } public boolean isHasHelp() { return hasHelp; } public void setHasHelp(boolean hasHelp) { this.hasHelp = hasHelp; } public boolean isHasAbout() { return hasAbout; } public void setHasAbout(boolean hasAbout) { this.hasAbout = hasAbout; } public Map<String, Attribute> getParameters() { return parameters; } public void setParameters(Map<String, Attribute> parameters) { this.parameters = parameters; } public Map<String, StringListAttribute> getPortletPreferences() { return this.portletPreferences; } public void setPortletPreferences(Map<String, StringListAttribute> portletParameters) { this.portletPreferences = portletParameters; } public Map<String, BooleanAttribute> getPortletPreferenceReadOnly() { return this.portletPreferenceReadOnly; } public void setPortletPreferenceReadOnly( Map<String, BooleanAttribute> portletPreferenceReadOnly) { this.portletPreferenceReadOnly = portletPreferenceReadOnly; } public SortedSet<JsonEntityBean> getPrincipals() { return Collections.unmodifiableSortedSet(principals); } public void setPrincipals(SortedSet<JsonEntityBean> principals) { this.principals.clear(); this.principals.addAll(principals); } public void addPrincipal(JsonEntityBean principal) { this.principals.add(principal); } public Set<String> getPermissions() { return Collections.unmodifiableSet(permissions); } public void setPermissions(Set<String> permissions) { this.permissions.clear(); this.permissions.addAll(permissions); } public void addPermission(String permission) { permissions.add(permission); } public void clearPermissions() { this.permissions.clear(); } public SortedSet<JsonEntityBean> getCategories() { return Collections.unmodifiableSortedSet(categories); } public void setCategories(SortedSet<JsonEntityBean> categories) { this.categories.clear(); this.categories.addAll(categories); } public void addCategory(JsonEntityBean category) { this.categories.add(category); } public int getPublishHour() { return this.publishHour; } public void setPublishHour(int publishHour) { this.publishHour = publishHour; } public int getPublishMinute() { return this.publishMinute; } public void setPublishMinute(int publishMinute) { this.publishMinute = publishMinute; } public int getPublishAmPm() { return this.publishAmPm; } public void setPublishAmPm(int publishAmPm) { this.publishAmPm = publishAmPm; } public int getExpirationHour() { return this.expirationHour; } public void setExpirationHour(int expirationHour) { this.expirationHour = expirationHour; } public int getExpirationMinute() { return this.expirationMinute; } public void setExpirationMinute(int expirationMinute) { this.expirationMinute = expirationMinute; } public int getExpirationAmPm() { return this.expirationAmPm; } public void setExpirationAmPm(int expirationAmPm) { this.expirationAmPm = expirationAmPm; } /** * Return the full date and time at which this portlet shoudl be automatically published. This * value is built from the individual date/time fields. * * @return */ public Date getPublishDateTime() { if (this.getPublishDate() == null) { return null; } Calendar cal = Calendar.getInstance(); cal.setTime(this.getPublishDate()); cal.set(Calendar.HOUR, this.getPublishHour()); cal.set(Calendar.MINUTE, this.getPublishMinute()); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.AM_PM, this.getPublishAmPm()); return cal.getTime(); } /** * Return the full date and time at which this portlet shoudl be automatically expired. This * value is built from the individual date/time fields. * * @return */ public Date getExpirationDateTime() { if (this.getExpirationDate() == null) { return null; } Calendar cal = Calendar.getInstance(); cal.setTime(this.getExpirationDate()); cal.set(Calendar.HOUR, this.getExpirationHour()); cal.set(Calendar.MINUTE, this.getExpirationMinute()); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.set(Calendar.AM_PM, this.getExpirationAmPm()); return cal.getTime(); } /** * Get the expiration date as a string. This is just webflow workaround. * * @return the expiration date as a string */ public String getExpirationDateString() { if (expirationDate == null) { return null; } return dateFormat.format(expirationDate); } /** * Set the expiration date as a string. * * @param date the date string * @throws ParseException if the string cannot be parsed */ public void setExpirationDateString(String date) throws ParseException { if (StringUtils.isBlank(date)) { expirationDate = null; return; } expirationDate = dateFormat.parse(date); } public void setPublishDateTime(Date publish) { if (publish != null) { this.setPublishDate(publish); Calendar cal = Calendar.getInstance(); cal.setTime(publish); if (cal.get(Calendar.HOUR) == 0) { this.setPublishHour(12); } else { this.setPublishHour(cal.get(Calendar.HOUR)); } this.setPublishMinute(cal.get(Calendar.MINUTE)); this.setPublishAmPm(cal.get(Calendar.AM_PM)); } } /** * Get the publish date as a string. * * @return the publish date as a string */ public String getPublishDateString() { if (publishDate == null) { return null; } return dateFormat.format(publishDate); } /** * Set the publish date as a string. This is just a webflow workaround. * * @param date the date string * @throws ParseException if the date cannot be parsed */ public void setPublishDateString(String date) throws ParseException { if (StringUtils.isBlank(date)) { publishDate = null; return; } publishDate = dateFormat.parse(date); } public void setExpirationDateTime(Date expire) { if (expire != null) { this.setExpirationDate(expire); Calendar cal = Calendar.getInstance(); cal.setTime(expire); if (cal.get(Calendar.HOUR) == 0) { this.setExpirationHour(12); } else { this.setExpirationHour(cal.get(Calendar.HOUR)); } this.setExpirationMinute(cal.get(Calendar.MINUTE)); this.setExpirationAmPm(cal.get(Calendar.AM_PM)); } } }