/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.gatein.api.site; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashSet; import java.util.Locale; import java.util.Set; import org.apache.commons.lang.LocaleUtils; import org.exoplatform.container.RootContainer; import org.exoplatform.container.monitor.jvm.J2EEServerInfo; import org.exoplatform.portal.config.DataStorage; import org.exoplatform.portal.config.UserPortalConfigService; import org.exoplatform.portal.config.model.PortalConfig; import org.exoplatform.portal.config.model.Properties; import org.exoplatform.portal.mop.SiteKey; import org.exoplatform.portal.pom.data.PortalData; import org.gatein.api.ApiException; import org.gatein.api.EntityAlreadyExistsException; import org.gatein.api.Util; import org.gatein.api.common.Attributes; import org.gatein.api.internal.ObjectToStringBuilder; import org.gatein.api.internal.Parameters; import org.gatein.api.security.Group; import org.gatein.api.security.Permission; import org.gatein.api.security.User; /** * @author <a href="mailto:nscavell@redhat.com">Nick Scavelli</a> */ public class SiteImpl implements Site { private final SiteId id; private transient PortalConfig portalConfig; private Attributes attributes; private boolean create; private String templateName; // only used when creating a site private Set<String> changed = new HashSet<String>(); // only used to know what fields were set after a create so we can replay properly public SiteImpl(SiteId id, String templateName) { this.id = id; SiteKey siteKey = Util.from(id); this.portalConfig = new PortalConfig(siteKey.getTypeName(), siteKey.getName()); this.attributes = new Attributes(); this.create = true; this.templateName = templateName; } public SiteImpl(PortalConfig portalConfig) { this.portalConfig = portalConfig; SiteKey siteKey = new SiteKey(portalConfig.getType(), portalConfig.getName()); this.id = Util.from(siteKey); this.attributes = Util.from(portalConfig.getProperties()); } @Override public SiteId getId() { return id; } @Override public SiteType getType() { return id.getType(); } @Override public String getName() { return id.getName(); } @Override public String getDescription() { return portalConfig.getDescription(); } @Override public void setDescription(String description) { if (create) changed.add("description"); portalConfig.setDescription(description); } @Override public void setDisplayName(String displayName) { if (create) changed.add("displayName"); portalConfig.setLabel(displayName); } @Override public String getDisplayName() { // TODO: For sites of type SiteType.SPACE this should return the label of the group return portalConfig.getLabel(); } @Override public Locale getLocale() { return Util.toLocale(portalConfig.getLocale()); } @Override public void setLocale(Locale locale) { if (create) changed.add("locale"); Parameters.requireNonNull(locale, "locale"); portalConfig.setLocale(Util.fromLocale(locale)); } @Override public String getSkin() { return portalConfig.getSkin(); } @Override public void setSkin(String skin) { if (create) changed.add("skin"); portalConfig.setSkin(skin); } @Override public Attributes getAttributes() { return attributes; } @Override public Permission getAccessPermission() { return Util.from(portalConfig.getAccessPermissions()); } @Override public void setAccessPermission(Permission permission) { if (create) changed.add("access"); portalConfig.setAccessPermissions(Util.from(permission)); } @Override public Permission getEditPermission() { return Util.from(portalConfig.getEditPermission()); } @Override public void setEditPermission(Permission permission) { Parameters.requireNonNull(permission, "permission", "To allow edit for everyone use Permission.everyone()"); // Only one edit permission (membership) is allowed at this time. String[] permissions = Util.from(permission); if (permissions.length != 1) throw new IllegalArgumentException("Invalid permission. Only one membership is allowed for an edit permission"); if (create) changed.add("edit"); portalConfig.setEditPermission(permissions[0]); } public void save(DataStorage storage, UserPortalConfigService service) { if (create) { try { PortalConfig existing = storage.getPortalConfig(portalConfig.getType(), portalConfig.getName()); if (existing != null) throw new EntityAlreadyExistsException("Cannot create site. Site " + id + " already exists."); } catch (Exception e) { throw new ApiException("Exception occurred checking if site already existed before creating site " + id, e); } // In order to properly create a site (which includes creating it from a template) it seemed much harder // to get it working properly (NewPortalConfigListener) if (areWeInATestEnvironment()) { try { storage.create(portalConfig); // Just create an empty site } catch (Exception e) { throw new ApiException("Exception creating site " + id + " in testing environment."); } } else { try { switch (id.getType()) { case SITE: service.createUserPortalConfig(portalConfig.getType(), portalConfig.getName(), templateName); break; case SPACE: service.createGroupSite(portalConfig.getName()); break; case DASHBOARD: service.createUserSite(portalConfig.getName()); break; } } catch (Exception e) { throw new ApiException("Could not create site " + id, e); } } // Retrieve the site that was created above and replay any changes done via the Site api object. PortalConfig created; try { created = storage.getPortalConfig(portalConfig.getType(), portalConfig.getName()); if (created == null) throw new ApiException("Could not find site after we successfully created it."); } catch (Exception e) { throw new ApiException("Exception occurred retrieving previously created site " + id); } SiteImpl createdSite = new SiteImpl(created); // Now replay/set the data that may have changed since the call from Portal.create to Portal.save if (changed.contains("access")) { createdSite.setAccessPermission(getAccessPermission()); } if (changed.contains("edit")) { createdSite.setEditPermission(getEditPermission()); } if (changed.contains("skin")) { createdSite.setSkin(getSkin()); } if (changed.contains("locale")) { createdSite.setLocale(getLocale()); } if (changed.contains("description")) { createdSite.setDescription(getDescription()); } if (changed.contains("displayName")) { createdSite.setDisplayName(getDisplayName()); } createdSite.getAttributes().putAll(getAttributes()); this.attributes = createdSite.getAttributes(); // Now we can set the internal PortalConfig object which should now properly reflect the site that was created // above and the changes done via the API this.portalConfig = createdSite.portalConfig; } // Attributes is the only object that can be modified outside the context of this object portalConfig.setProperties(Util.from(attributes)); try { storage.save(portalConfig); changed = null; create = false; templateName = null; } catch (Exception e) { throw new ApiException("Exception occurred trying to save site " + id, e); } } @Override public int compareTo(Site other) { return getName().compareTo(other.getName()); } @Override public String toString() { return ObjectToStringBuilder.toStringBuilder(getClass()).add("type", getType().getName()).add("name", getName()) .add("displayName", getDisplayName()).add("description", getDescription()).add("locale", getLocale()) .add("skin", getSkin()).add("attributes", getAttributes()).add("editPermission", getEditPermission()) .add("accessPermission", getAccessPermission()).toString(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); PortalData data = (PortalData) in.readObject(); portalConfig = new PortalConfig(data); } private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException { out.defaultWriteObject(); out.writeObject(portalConfig.build()); } private static boolean areWeInATestEnvironment() { J2EEServerInfo server = RootContainer.getInstance().getServerEnvironment(); String serverName = (server == null) ? null : server.getServerName(); return ("test".equals(serverName) || "standalone".equals(serverName)); } }