- More JAXB mapping annotations
- Started to migrate authentication system


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3496 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2015-06-22 17:30:58 +00:00
parent d1baf9e8e7
commit 7f2da80e81
19 changed files with 689 additions and 169 deletions

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.categorization;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class CategorizationConstants {
public static final String CAT_XML_NS = "http://categorization.libreccm.org";
private CategorizationConstants() {
//Nothing
}
}

View File

@ -273,7 +273,7 @@ public class CategoryManager {
* {@code null}. * {@code null}.
* *
* @throws NotASubCategoryException If one or both categories are not * @throws NotASubCategoryException If one or both categories are not
* subcategories of the provided parent category. * subcategories of the provided parent category.qq
*/ */
public void swapCategories(final Category subCategoryA, public void swapCategories(final Category subCategoryA,
final Category subCategoryB, final Category subCategoryB,

View File

@ -20,9 +20,13 @@ package org.libreccm.categorization;
import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.URL; import org.hibernate.validator.constraints.URL;
import static org.libreccm.categorization.CategorizationConstants.*;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.jpa.utils.UriConverter; import org.libreccm.jpa.utils.UriConverter;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import org.libreccm.web.Application;
import java.io.Serializable; import java.io.Serializable;
import java.net.URI; import java.net.URI;
@ -48,21 +52,26 @@ import javax.validation.constraints.Pattern;
import org.omg.CORBA.DomainManager; import org.omg.CORBA.DomainManager;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/** /**
* A domain is collection of categories designed a specific purpose. This entity * A domain is collection of categories designed a specific purpose. This entity
* replaces the {@code Domain} entity from the old {@code ccm-ldn-terms} module * replaces the {@code Domain} entity from the old {@code ccm-ldn-terms} module
* as well as the {@code CategoryPurpose} entity from the old * as well as the {@code CategoryPurpose} entity from the old
* {@code ccm-core module}. * {@code ccm-core module}.
* *
* A {@code Domain} can be mapped to multiple {@link CcmObject}s. Normally this * A {@code Domain} can be mapped to multiple {@link Application}s. Normally
* is used to make a {@code Domain} available in a application. The * This is used to make a {@code Domain} available in the application. The
* {@link CcmObject}s to which a {@code Domain} is mapped are called * {@link Application}s to which a {@code Domain} is mapped are called
* <em>owners</em> of the domain. * <em>owners</em> of the domain.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@Entity @Entity
@Table(name = "category_domains") @Table(name = "category_domains")
@XmlRootElement(name = "domain", namespace = CAT_XML_NS)
public class Domain extends CcmObject implements Serializable { public class Domain extends CcmObject implements Serializable {
private static final long serialVersionUID = 4012590760598188732L; private static final long serialVersionUID = 4012590760598188732L;
@ -75,6 +84,7 @@ public class Domain extends CcmObject implements Serializable {
@Column(name = "domain_key", nullable = false, unique = true, length = 255) @Column(name = "domain_key", nullable = false, unique = true, length = 255)
@NotBlank @NotBlank
@Pattern(regexp = "[\\w-.]*") @Pattern(regexp = "[\\w-.]*")
@XmlElement(name = "domain-key", namespace = CAT_XML_NS)
private String domainKey; private String domainKey;
/** /**
@ -89,10 +99,11 @@ public class Domain extends CcmObject implements Serializable {
* http://example.org/domains/example-nav * http://example.org/domains/example-nav
* </pre> * </pre>
*/ */
@Column(name = "uri", nullable = false, length = 2048) @Column(name = "uri", nullable = false, unique = true, length = 2048)
@Convert(converter = UriConverter.class) @Convert(converter = UriConverter.class)
@NotBlank @NotBlank
@URL @URL
@XmlElement(name = "uri", namespace = CAT_XML_NS)
private URI uri; private URI uri;
/** /**
@ -105,6 +116,7 @@ public class Domain extends CcmObject implements Serializable {
joinTable = @JoinTable(name = "domain_titles", joinTable = @JoinTable(name = "domain_titles",
joinColumns = { joinColumns = {
@JoinColumn(name = "object_id")})) @JoinColumn(name = "object_id")}))
@XmlElement(name = "title", namespace = CAT_XML_NS)
private LocalizedString title; private LocalizedString title;
/** /**
@ -116,6 +128,7 @@ public class Domain extends CcmObject implements Serializable {
joinTable = @JoinTable(name = "domain_descriptions", joinTable = @JoinTable(name = "domain_descriptions",
joinColumns = { joinColumns = {
@JoinColumn(name = "object_id")})) @JoinColumn(name = "object_id")}))
@XmlElement(name = "description", namespace = CAT_XML_NS)
private LocalizedString description; private LocalizedString description;
/** /**
@ -123,6 +136,7 @@ public class Domain extends CcmObject implements Serializable {
*/ */
@Column(name = "version", nullable = false) @Column(name = "version", nullable = false)
@NotBlank @NotBlank
@XmlElement(name = "version", namespace = CAT_XML_NS)
private String version; private String version;
/** /**
@ -130,6 +144,7 @@ public class Domain extends CcmObject implements Serializable {
*/ */
@Column(name = "released") @Column(name = "released")
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
@XmlElement(name = "released", namespace = CAT_XML_NS)
private Date released; private Date released;
/** /**
@ -137,12 +152,14 @@ public class Domain extends CcmObject implements Serializable {
*/ */
@ManyToOne @ManyToOne
@JoinColumn(name = "root_category_id") @JoinColumn(name = "root_category_id")
@XmlElement(name = "root", namespace = CAT_XML_NS)
private Category root; private Category root;
/** /**
* The owners of the domain. * The owners of the domain.
*/ */
@OneToMany(mappedBy = "domain") @OneToMany(mappedBy = "domain")
@XmlElementWrapper(name = "owners", namespace = CAT_XML_NS)
private List<DomainOwnership> owners; private List<DomainOwnership> owners;
public Domain() { public Domain() {

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.categorization;
import org.libreccm.web.Application;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
* Provides several methods when managing the relations between {@link Domain}s
* and their owning {@link Application}s.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class DomainManager {
@Inject
private transient DomainRepository domainRepo;
/**
* Adds a {@code Application} to the owners of a {@link Domain}. If the
* provided {@code Application} is already an owner of the provided
* {@code Domain} the method does nothing.
*
* @param application The {@code Application} to add to the owners of the
* {@code Domain}.
* @param domain The {@code Domain} to which owners the
* {@code Application is added}.
*/
public void addDomainOwner(final Application application,
final Domain domain) {
throw new UnsupportedOperationException();
}
/**
* Removes a {@code Application} from the owners of a {@code Domain}. If the
* provided {@code Application} is not an owner of the provided
* {@code Domain} the method does nothing.
*
* @param application The {@code Application} to remove from the owners of
* the provided {@code Domain}.
* @param domain The {@code Domain} from which owners the provided
* {@code Application} should be removed.
*/
public void removeDomainOwner(final Application application,
final Domain domain) {
throw new UnsupportedOperationException();
}
/**
* Determines if a {@link Application} is an owner of {@link Domain}.
*
* @param application The {@code Application} to test.
* @param domain The {@code Domain} to test.
* @return {@code true} if the provided {@code Application} is an owner
* of the provided {@code Domain}, {@code false} otherwise.
*/
public boolean isDomainOwner(final Application application,
final Domain domain) {
throw new UnsupportedOperationException();
}
}

View File

@ -20,6 +20,7 @@ package org.libreccm.categorization;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
@ -27,7 +28,9 @@ import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.web.Application;
/** /**
* Association class for the association between a {@link Domain} and a * Association class for the association between a {@link Domain} and a
@ -55,7 +58,7 @@ public class DomainOwnership implements Serializable {
* The {@link CcmObject} owning the {@link Domain}. * The {@link CcmObject} owning the {@link Domain}.
*/ */
@ManyToOne(optional = false) @ManyToOne(optional = false)
private CcmObject owner; private Application owner;
/** /**
* The {@link Domain} owned by the {@link CcmObject}. * The {@link Domain} owned by the {@link CcmObject}.
@ -91,11 +94,11 @@ public class DomainOwnership implements Serializable {
this.ownershipId = ownershipId; this.ownershipId = ownershipId;
} }
public CcmObject getOwner() { public Application getOwner() {
return owner; return owner;
} }
protected void setOwner(final CcmObject owner) { protected void setOwner(final Application owner) {
this.owner = owner; this.owner = owner;
} }

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.categorization;
import org.libreccm.core.AbstractEntityRepository;
import java.net.URI;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
/**
* A repository for executing CRUD operations on {@link Domain} objects.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class DomainRepository extends AbstractEntityRepository<Long, Domain> {
@Inject
private transient EntityManager entityManager;
@Override
public Class<Domain> getEntityClass() {
return Domain.class;
}
@Override
public boolean isNew(final Domain entity) {
return entity.getObjectId() == 0;
}
/**
* Find the {@link Domain} identified by the provided {@code domainKey}.
*
* @param domainKey The domain key of the {@code Domain} to find.
*
* @return The {@code Domain} identified by {@code domainKey} or
* {@code null} if there is no such {@code Domain}.
*/
public Domain findByDomainKey(final String domainKey) {
throw new UnsupportedOperationException();
}
/**
* Find the {@link Domain} identified the provided {@code uri}.
*
* @param uri The URI of the domain to find.
*
* @return The {@code Domain} identified by the provided URI or {@code null}
* if there is so such {@code Domain}.
*/
public Domain findByUri(final URI uri) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
@XmlSchema(xmlns = {@XmlNs(prefix = "cat", namespaceURI = CAT_XML_NS)})
@XmlAccessorType(XmlAccessType.NONE)
package org.libreccm.categorization;
import static org.libreccm.categorization.CategorizationConstants.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;

View File

@ -22,9 +22,7 @@ import static org.libreccm.core.CoreConstants.*;
import org.libreccm.categorization.Categorization; import org.libreccm.categorization.Categorization;
import org.libreccm.categorization.Category; import org.libreccm.categorization.Category;
import org.libreccm.categorization.Domain; import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.DomainOwnership;
import org.omg.CORBA.DomainManager;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -46,21 +44,21 @@ import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/** /**
* Root class of all entities in LibreCCM which need categorisation and * Root class of all entities in LibreCCM which need categorisation and
* permission services. * permission services.
* *
* This class defines several basic properties including associations * This class defines several basic properties including associations to
* to {@link Category} (via the {@link Categorization} class and permissions. * {@link Category} (via the {@link Categorization} class and permissions.
* *
* In the old hierarchy the equivalent of this class was the {@code ACSObject} * In the old hierarchy the equivalent of this class was the {@code ACSObject}
* entity. * entity.
* *
* We are using the {@code JOINED} inheritance strategy for the inheritance * We are using the {@code JOINED} inheritance strategy for the inheritance
* hierarchy of this class to achieve modularity and to minimise duplicate data * hierarchy of this class to achieve modularity and to minimise duplicate data
* in the database. * in the database.
* *
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* *
*/ */
@Entity @Entity
@Table(name = "ccm_objects") @Table(name = "ccm_objects")
@ -75,9 +73,8 @@ public class CcmObject implements Serializable {
private static final long serialVersionUID = 201504261329L; private static final long serialVersionUID = 201504261329L;
/** /**
* The ID/primary key for the {@code CcmObject}. Please note that it is * The ID/primary key for the {@code CcmObject}. Please note that it is not
* not necessary to define an additional ID on classes which extend this * necessary to define an additional ID on classes which extend this class.
* class.
*/ */
@Id @Id
@Column(name = "object_id") @Column(name = "object_id")
@ -96,15 +93,7 @@ public class CcmObject implements Serializable {
@XmlElementWrapper(name = "permissions", namespace = CORE_XML_NS) @XmlElementWrapper(name = "permissions", namespace = CORE_XML_NS)
@XmlElement(name = "permission", namespace = CORE_XML_NS) @XmlElement(name = "permission", namespace = CORE_XML_NS)
private List<Permission> permissions; private List<Permission> permissions;
/**
* Category Domains owned by this {@code CcmObject}.
*/
@OneToMany(mappedBy = "owner")
@XmlElementWrapper(name = "domains", namespace = CORE_XML_NS)
@XmlElement(name = "domain", namespace = CORE_XML_NS)
private List<DomainOwnership> domains;
/** /**
* Categories which have been assigned to this {@code CcmObject}. * Categories which have been assigned to this {@code CcmObject}.
*/ */
@ -112,15 +101,14 @@ public class CcmObject implements Serializable {
@XmlElementWrapper(name = "categories", namespace = CORE_XML_NS) @XmlElementWrapper(name = "categories", namespace = CORE_XML_NS)
@XmlElement(name = "category", namespace = CORE_XML_NS) @XmlElement(name = "category", namespace = CORE_XML_NS)
private List<Categorization> categories; private List<Categorization> categories;
public CcmObject() { public CcmObject() {
super(); super();
permissions = new ArrayList<>(); permissions = new ArrayList<>();
domains = new ArrayList<>();
categories = new ArrayList<>(); categories = new ArrayList<>();
} }
public long getObjectId() { public long getObjectId() {
return objectId; return objectId;
} }
@ -138,10 +126,11 @@ public class CcmObject implements Serializable {
} }
/** /**
* *
* @return Returns all permissions for this {@code CcmObject}. Please note * @return Returns all permissions for this {@code CcmObject}. Please note
* that the returned {@link List} can't be modified. For adding and removing * that the returned {@link List} can't be modified. For adding and
* permissions use the methods provided by the {@link CcmObjectManager}. * removing permissions use the methods provided by the
* {@link CcmObjectManager}.
*/ */
public List<Permission> getPermissions() { public List<Permission> getPermissions() {
return Collections.unmodifiableList(permissions); return Collections.unmodifiableList(permissions);
@ -154,92 +143,49 @@ public class CcmObject implements Serializable {
protected void addPermission(final Permission permission) { protected void addPermission(final Permission permission) {
permissions.add(permission); permissions.add(permission);
} }
protected void removePermission(final Permission permission) { protected void removePermission(final Permission permission) {
permissions.remove(permission); permissions.remove(permission);
} }
/**
* Gets an <strong>unmodifiable</strong> list of the domains which are owned
* by the {@code CcmObject}.
*
* @return An unmodifiable list of the domain ownerships of this
* {@code CcmObject}. Might be {@code null} or empty.
*/
public List<DomainOwnership> getDomains() {
return Collections.unmodifiableList(domains);
}
/** /**
* Setter for the list of domain ownerships, only for use by JPA. * Returns a <strong>unmodifiable</strong> list of the categories this
*
* @param domains A list of domain ownerships.
*/
protected void setDomains(final List<DomainOwnership> domains) {
this.domains = domains;
}
/**
* <strong>Internal</strong> method for adding a domain ownership.
* Users should use the appropriate methods of the {@link DomainManager}
* class to
* manage the {@link Domain}s assigned to {@code CcmObject}.
*
* @param domain The domain ownership to add.
*/
protected void addDomain(final DomainOwnership domain) {
domains.add(domain);
}
/**
* <strong>Internal</strong> method for removing a domain ownership.
* Users should use the appropriate methods of the {@link DomainManager} to
* manage the {@link Domain}s assigned to {@code CcmObject}.
*
* @param domain The domain to remove.
*/
protected void removeDomain(final DomainOwnership domain) {
domains.remove(domain);
}
/**
* Returns a <strong>unmodifiable</strong> list of the categories this
* object is assigned to. To manage the categories of a {@code CcmObject} * object is assigned to. To manage the categories of a {@code CcmObject}
* use the methods provided by the {@link CategoryManager} class. * use the methods provided by the {@link CategoryManager} class.
* *
* @return An <strong>unmodifiable</strong> list of the categories of this * @return An <strong>unmodifiable</strong> list of the categories of this
* {@code CcmObject}. Might be {@code null} or empty. * {@code CcmObject}. Might be {@code null} or empty.
*/ */
public List<Categorization> getCategories() { public List<Categorization> getCategories() {
return Collections.unmodifiableList(categories); return Collections.unmodifiableList(categories);
} }
/** /**
* Setter for the list of categories assigned to this {@code CcmObject}, * Setter for the list of categories assigned to this {@code CcmObject},
* only for use by JPA. * only for use by JPA.
* *
* @param categories A list of domain ownerships. * @param categories A list of domain ownerships.
*/ */
protected void setCategories(final List<Categorization> categories) { protected void setCategories(final List<Categorization> categories) {
this.categories = categories; this.categories = categories;
} }
/** /**
* <strong>Internal</strong> method for adding a category. * <strong>Internal</strong> method for adding a category. Users should use
* Users should use the appropriate methods of the {@link CategoryManager} * the appropriate methods of the {@link CategoryManager} class to manage
* class to manage the categories assigned to a {@code CcmObject}. * the categories assigned to a {@code CcmObject}.
* *
* @param category The domain ownership to add. * @param category The domain ownership to add.
*/ */
protected void addCategory(final Categorization category) { protected void addCategory(final Categorization category) {
categories.add(category); categories.add(category);
} }
/** /**
* <strong>Internal</strong> method for removing a assigned category. * <strong>Internal</strong> method for removing a assigned category. Users
* Users should use the appropriate methods of the {@link CategoryManager} * should use the appropriate methods of the {@link CategoryManager} to
* to manage the categories assigned to a {@code CcmObject}. * manage the categories assigned to a {@code CcmObject}.
* *
* @param category The assigned category to remove. * @param category The assigned category to remove.
*/ */
protected void removeCategory(final Categorization category) { protected void removeCategory(final Categorization category) {
@ -255,45 +201,47 @@ public class CcmObject implements Serializable {
} }
/** /**
* Implementation of the {@code equals(Object)} method for {@code CcmObject}. We are * Implementation of the {@code equals(Object)} method for
* using the <em>canEqual</em> approach described at * {@code CcmObject}. We are using the <em>canEqual</em> approach described
* at
* http://www.jqno.nl/equalsverifier/2011/01/20/subclass-object-is-not-equal-to-an-instance-of-a-trivial-subclass-with-equal-fields/ * http://www.jqno.nl/equalsverifier/2011/01/20/subclass-object-is-not-equal-to-an-instance-of-a-trivial-subclass-with-equal-fields/
* here. Therefore, in addition to overwrite this method subclasses should * here. Therefore, in addition to overwrite this method subclasses should
* also overwrite the {@link #canEqual(java.lang.Object)} method. * also overwrite the {@link #canEqual(java.lang.Object)} method.
* *
* A good pattern for implementing {@code equals(Object)} is the following * A good pattern for implementing {@code equals(Object)} is the following
* (this is similar to {@code equals(Object)} implemenation created by * (this is similar to {@code equals(Object)} implemenation created by
* Netbeans): * Netbeans):
* *
* <pre> * <pre>
* public boolean equals(final Object obj) { * public boolean equals(final Object obj) {
* //Check if obj is null * //Check if obj is null
* if (obj == null) { * if (obj == null) {
* return false; * return false;
* } * }
* *
* //Check if obj is an instance of the class implementing equals * //Check if obj is an instance of the class implementing equals
* if (!(obj instanceof YourClass)) { * if (!(obj instanceof YourClass)) {
* return false; * return false;
* } * }
* *
* //Cast obj to the specific class * //Cast obj to the specific class
* final YourClass other = (YourClass) obj; * final YourClass other = (YourClass) obj;
* //Check if other can equal YourClass * //Check if other can equal YourClass
* if (!other.canEqual(this) { * if (!other.canEqual(this) {
* return false; * return false;
* } * }
* *
* if(!super.equals(obj) { * if(!super.equals(obj) {
* return false; * return false;
* } * }
* *
* //Check properties of YourClass * //Check properties of YourClass
* ... * ...
* } * }
* </pre> * </pre>
* *
* @param obj {@inheritDoc} * @param obj {@inheritDoc}
*
* @return {@inheritDoc} * @return {@inheritDoc}
*/ */
@Override @Override
@ -316,18 +264,19 @@ public class CcmObject implements Serializable {
} }
/** /**
* The {@code canEqual(Object} method is a helper method for * The {@code canEqual(Object} method is a helper method for
* {@link #equals(java.lang.Object)}. Subclasses which overwrite * {@link #equals(java.lang.Object)}. Subclasses which overwrite
* {@code #equals(Object)} must override this method also. * {@code #equals(Object)} must override this method also.
* *
* Usually the implementation of this method will be a onliner: * Usually the implementation of this method will be a onliner:
* <pre> * <pre>
* public boolean canEqual(final Object obj) { * public boolean canEqual(final Object obj) {
* return obj instanceof YourClass; * return obj instanceof YourClass;
* } * }
* </pre> * </pre>
* *
* @param obj The object to check. * @param obj The object to check.
*
* @return {@code true} if {@link obj} can equal this, false otherwise. * @return {@code true} if {@link obj} can equal this, false otherwise.
*/ */
public boolean canEqual(final Object obj) { public boolean canEqual(final Object obj) {
@ -336,11 +285,11 @@ public class CcmObject implements Serializable {
/** /**
* Implementation of the {@code toString()} method for {@code CcmObject}. To * Implementation of the {@code toString()} method for {@code CcmObject}. To
* make extension easy {@code toString()} simply calls * make extension easy {@code toString()} simply calls
* {@link #toString(java.lang.String)} with an empty string as parameter. * {@link #toString(java.lang.String)} with an empty string as parameter.
* Subclasses should not overwrite {@code toString}, instead they should use * Subclasses should not overwrite {@code toString}, instead they should use
* {@link #toString(java.lang.String)}. * {@link #toString(java.lang.String)}.
* *
* @return {@inheritDoc} * @return {@inheritDoc}
*/ */
@Override @Override
@ -350,33 +299,34 @@ public class CcmObject implements Serializable {
/** /**
* Creates a string representation of this object. Example: * Creates a string representation of this object. Example:
* *
* <pre> * <pre>
* org.libreccm.core.CcmObject@1adafefe4222{ objectId = 42, * org.libreccm.core.CcmObject@1adafefe4222{ objectId = 42,
* displayName = "example" } * displayName = "example" }
* </pre> * </pre>
* *
* Subclasses can simply add their properties by creating a containing the * Subclasses can simply add their properties by creating a containing the
* additional properties and call {@code super.toString(String)} with this * additional properties and call {@code super.toString(String)} with this
* data. The string should start with a leading space and comma because the * data. The string should start with a leading space and comma because the
* additional properties are inserted after the {@code displayName} in the * additional properties are inserted after the {@code displayName} in the
* string. Also an overwriting method should insert its own data parameter * string. Also an overwriting method should insert its own data parameter
* and the end of the string it creates. * and the end of the string it creates.
* *
* Collections should not be included in this string. Associated objects * Collections should not be included in this string. Associated objects
* might be included. In that case their representation should like this: * might be included. In that case their representation should like this:
* <pre> * <pre>
* someObject = { ... } * someObject = { ... }
* </pre> * </pre>
* *
* The content of the curly braces should be the string representation of * The content of the curly braces should be the string representation of
* the object. If the object is very complex it might be sufficent to * the object. If the object is very complex it might be sufficent to
* include only a subset of the objects properties. * include only a subset of the objects properties.
* *
* Likewise, strings would be enclosed by quotes. The value of date * Likewise, strings would be enclosed by quotes. The value of date
* properties should be shown in ISO format. * properties should be shown in ISO format.
* *
* @param data data from a subclass * @param data data from a subclass
*
* @return A string representation of this object. * @return A string representation of this object.
*/ */
public String toString(final String data) { public String toString(final String data) {
@ -386,7 +336,7 @@ public class CcmObject implements Serializable {
+ "displayName = \"%s\"" + "displayName = \"%s\""
+ "%s" + "%s"
+ " }", + " }",
super.toString(), super.toString(),
objectId, objectId,
displayName, displayName,
data); data);

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.core;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
/**
* This bean stores several datas about the current session, for example the
* current party.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@SessionScoped
public class CcmSessionContext implements Serializable {
private static final long serialVersionUID = 6110177865273823685L;
private Party currentParty;
private Party effectiveParty;
public Party getCurrentParty() {
return currentParty;
}
public void setCurrentParty(final Party currentParty) {
this.currentParty = currentParty;
this.effectiveParty = currentParty;
}
public Party getEffectiveParty() {
return effectiveParty;
}
protected void setEffectiveParty(final Party effectiveParty) {
this.effectiveParty = effectiveParty;
}
/**
* Execute code under different privileges. Useful if no current user is
* available, for example in the startup phase.
*
* The there is a current user the method will check if the current user
* has the permission to use the {@code sudo} method.
*
* @param party The party with which permissions the code is executed.
* @param runnable The code to execute.
*/
public void sudo(final Party party, final Runnable runnable) {
//ToDo: Check if current user is permitted to use sudo.
effectiveParty = party;
runnable.run();
effectiveParty = currentParty;
}
}

View File

@ -45,7 +45,9 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlTransient;
/** /**
* * The {@code User} entity stores the name and the password of a user along with
* some other informations.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@Entity @Entity
@ -53,7 +55,7 @@ import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name = "user", namespace = CORE_XML_NS) @XmlRootElement(name = "user", namespace = CORE_XML_NS)
//Supressing a few warnings from PMD because they misleading here. //Supressing a few warnings from PMD because they misleading here.
//User is perfectly fine class name, and the complexity is not to high... //User is perfectly fine class name, and the complexity is not to high...
@SuppressWarnings({"PMD.ShortClassName", @SuppressWarnings({"PMD.ShortClassName",
"PMD.CyclomaticComplexity", "PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity", "PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity"}) "PMD.ModifiedCyclomaticComplexity"})
@ -61,6 +63,9 @@ public class User extends Party implements Serializable {
private static final long serialVersionUID = 892038270064849732L; private static final long serialVersionUID = 892038270064849732L;
/**
* The real name of the user. We are using an {@code Embeddable} here.
*/
@Embedded @Embedded
@AssociationOverride( @AssociationOverride(
name = "user_names", name = "user_names",
@ -70,35 +75,82 @@ public class User extends Party implements Serializable {
@XmlElement(name = "person-name", namespace = CORE_XML_NS) @XmlElement(name = "person-name", namespace = CORE_XML_NS)
private PersonName name; private PersonName name;
/**
* A user name of the user. Usually an abbreviation of the users real name.
* For example a the <em>John Doe</em> might have the scree name
* <code>jdoe</code>. The screen name is used as user name for logins (if
* the system if configured so, otherwise the email address of the user is
* used).
*/
@Column(name = "screen_name", length = 255, nullable = false) @Column(name = "screen_name", length = 255, nullable = false)
@NotBlank @NotBlank
@XmlElement(name = "screen-name", namespace = CORE_XML_NS) @XmlElement(name = "screen-name", namespace = CORE_XML_NS)
private String screenName; private String screenName;
/**
* A user can be banned which means that he or she can't login into the
* system anymore.
*/
@Column(name = "banned") @Column(name = "banned")
@XmlElement(name = "banned", namespace = CORE_XML_NS) @XmlElement(name = "banned", namespace = CORE_XML_NS)
private boolean banned; private boolean banned;
/**
* An alias for the user used in an another system for SSO, for example LDAP.
*/
@Column(name = "sso_login", length = 512) @Column(name = "sso_login", length = 512)
@XmlElement(name = "sso-login", namespace = CORE_XML_NS) @XmlElement(name = "sso-login", namespace = CORE_XML_NS)
private String ssoLogin; private String ssoLogin;
/**
* The hashed password of the user.
*/
@Column(name = "password", length = 2048) @Column(name = "password", length = 2048)
@XmlTransient @XmlTransient
private String password; private String password;
/**
* The salt used to hash the password.
*/
@Column(name = "salt", length = 2048) @Column(name = "salt", length = 2048)
@XmlTransient @XmlTransient
private String salt; private String salt;
/**
* The hash algorithm used to hash the password. This allows us
* the change to another, stronger hash algorithm without invalidating
* existing accounts. The algorithm to use for new passwords can be
* configured by the administrator.
*
*/
@Column(name = "hash_algorithm", length = 64)
@XmlTransient
private String hashAlgorithm;
/**
* Indicates that the user should be forced to change his or her password
* on the next login.
*/
@Column(name = "password_reset_required")
private boolean passwordResetRequired;
/**
* Question the recover a forgotten password.
*/
@Column(name = "password_question", length = 2048) @Column(name = "password_question", length = 2048)
@XmlElement(name = "password-question", namespace = CORE_XML_NS) @XmlElement(name = "password-question", namespace = CORE_XML_NS)
private String passwordQuestion; private String passwordQuestion;
/**
* Answer the the {@link #passwordQuestion}.
*/
@Column(name = "password_answer", length = 2048) @Column(name = "password_answer", length = 2048)
@XmlElement(name = "password-answer", namespace = CORE_XML_NS) @XmlElement(name = "password-answer", namespace = CORE_XML_NS)
private String passwordAnswer; private String passwordAnswer;
/**
* The groups of which the user is a member.
*/
@OneToMany(mappedBy = "user") @OneToMany(mappedBy = "user")
@XmlElementWrapper(name = "group-memberships") @XmlElementWrapper(name = "group-memberships")
@XmlElement(name = "group-membership", namespace = CORE_XML_NS) @XmlElement(name = "group-membership", namespace = CORE_XML_NS)
@ -106,10 +158,11 @@ public class User extends Party implements Serializable {
public User() { public User() {
super(); super();
name = new PersonName();
this.groupMemberships = new ArrayList<>(); this.groupMemberships = new ArrayList<>();
} }
public PersonName getName() { public PersonName getName() {
return name; return name;
} }
@ -158,6 +211,22 @@ public class User extends Party implements Serializable {
this.salt = salt; this.salt = salt;
} }
public String getHashAlgorithm() {
return hashAlgorithm;
}
public void setHashAlgorithm(final String hashAlgorithm) {
this.hashAlgorithm = hashAlgorithm;
}
public boolean isPasswordResetRequired() {
return passwordResetRequired;
}
public void setPasswordResetRequired(final boolean passwordResetRequired) {
this.passwordResetRequired = passwordResetRequired;
}
public String getPasswordQuestion() { public String getPasswordQuestion() {
return passwordQuestion; return passwordQuestion;
} }
@ -195,14 +264,16 @@ public class User extends Party implements Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
int hash = super.hashCode(); int hash = super.hashCode();
hash = 59 * hash + Objects.hashCode(this.name); hash = 59 * hash + Objects.hashCode(name);
hash = 59 * hash + Objects.hashCode(this.screenName); hash = 59 * hash + Objects.hashCode(screenName);
hash = 59 * hash + (this.banned ? 1 : 0); hash = 59 * hash + (banned ? 1 : 0);
hash = 59 * hash + Objects.hashCode(this.ssoLogin); hash = 59 * hash + Objects.hashCode(ssoLogin);
hash = 59 * hash + Objects.hashCode(this.password); hash = 59 * hash + Objects.hashCode(password);
hash = 59 * hash + Objects.hashCode(this.salt); hash = 59 * hash + Objects.hashCode(salt);
hash = 59 * hash + Objects.hashCode(this.passwordQuestion); hash = 59 * hash + Objects.hashCode(hashAlgorithm);
hash = 59 * hash + Objects.hashCode(this.passwordAnswer); hash = 59 * hash + (passwordResetRequired ? 1 : 0);
hash = 59 * hash + Objects.hashCode(passwordQuestion);
hash = 59 * hash + Objects.hashCode(passwordAnswer);
return hash; return hash;
} }
@ -228,28 +299,37 @@ public class User extends Party implements Serializable {
return false; return false;
} }
if (!Objects.equals(this.name, other.getName())) { if (!Objects.equals(name, other.getName())) {
return false; return false;
} }
if (!Objects.equals(this.screenName, other.getScreenName())) { if (!Objects.equals(screenName, other.getScreenName())) {
return false; return false;
} }
if (this.banned != other.isBanned()) { if (banned != other.isBanned()) {
return false; return false;
} }
if (!Objects.equals(this.ssoLogin, other.getSsoLogin())) { if (!Objects.equals(ssoLogin, other.getSsoLogin())) {
return false; return false;
} }
if (!Objects.equals(this.password, other.getPassword())) { if (!Objects.equals(password, other.getPassword())) {
return false; return false;
} }
if (!Objects.equals(this.salt, other.getSalt())) { if (!Objects.equals(salt, other.getSalt())) {
return false; return false;
} }
if (!Objects.equals(this.passwordQuestion, other.getPasswordQuestion())) {
if (!Objects.equals(hashAlgorithm, other.getHashAlgorithm())) {
return false; return false;
} }
return Objects.equals(this.passwordAnswer, other.getPasswordAnswer());
if (passwordResetRequired != other.isPasswordResetRequired()) {
return false;
}
if (!Objects.equals(passwordQuestion, other.getPasswordQuestion())) {
return false;
}
return Objects.equals(passwordAnswer, other.getPasswordAnswer());
} }
@Override @Override
@ -262,11 +342,15 @@ public class User extends Party implements Serializable {
return super.toString(String.format(", name = %s, " return super.toString(String.format(", name = %s, "
+ "screenName = \"%s\", " + "screenName = \"%s\", "
+ "banned = %b, " + "banned = %b, "
+ "ssoLogin = \"%s\"%s", + "ssoLogin = \"%s\""
+ "hashAlgorithm = \"%s\""
+ "passwordResetRequired = %b%s",
Objects.toString(name), Objects.toString(name),
screenName, screenName,
banned, banned,
ssoLogin, ssoLogin,
hashAlgorithm,
passwordResetRequired,
data)); data));
} }

View File

@ -21,10 +21,12 @@
* This package provides some base classes for LibreCCM. * This package provides some base classes for LibreCCM.
*/ */
@XmlSchema(xmlns = {@XmlNs(prefix = "ccmcore", @XmlSchema(xmlns = {@XmlNs(prefix = "ccmcore",
namespaceURI = "http://core.libreccm.org")}) namespaceURI = CORE_XML_NS)})
@XmlAccessorType(XmlAccessType.NONE) @XmlAccessorType(XmlAccessType.NONE)
package org.libreccm.core; package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlNs;

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.l10n;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class L10NConstants {
public static final String L10N_XML_NS = "http://l10n.libreccm.org";
private L10NConstants() {
//Nothing
}
}

View File

@ -18,6 +18,8 @@
*/ */
package org.libreccm.l10n; package org.libreccm.l10n;
import static org.libreccm.l10n.L10NConstants.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -31,8 +33,6 @@ import javax.persistence.ElementCollection;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
import javax.persistence.Lob; import javax.persistence.Lob;
import javax.persistence.MapKeyColumn; import javax.persistence.MapKeyColumn;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
@ -46,8 +46,7 @@ import javax.xml.bind.annotation.XmlRootElement;
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@Embeddable @Embeddable
@XmlRootElement @XmlRootElement(name = "localized-string", namespace = L10N_XML_NS)
@XmlAccessorType(XmlAccessType.FIELD)
public class LocalizedString implements Serializable { public class LocalizedString implements Serializable {
private static final long serialVersionUID = 7378282657084330425L; private static final long serialVersionUID = 7378282657084330425L;
@ -59,8 +58,8 @@ public class LocalizedString implements Serializable {
@MapKeyColumn(name = "locale") @MapKeyColumn(name = "locale")
@Column(name = "localized_value") @Column(name = "localized_value")
@Lob @Lob
@XmlElementWrapper(name = "values") @XmlElementWrapper(name = "values", namespace = L10N_XML_NS)
@XmlElement(name = "value") @XmlElement(name = "value", namespace = L10N_XML_NS)
private Map<Locale, String> values; private Map<Locale, String> values;
/** /**

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
@XmlSchema(xmlns = {@XmlNs(prefix = "l10n", namespaceURI = L10N_XML_NS)})
@XmlAccessorType(XmlAccessType.NONE)
package org.libreccm.l10n;
import static org.libreccm.l10n.L10NConstants.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;

View File

@ -18,20 +18,31 @@
*/ */
package org.libreccm.web; package org.libreccm.web;
import static org.libreccm.web.WebConstants.*;
import org.libreccm.categorization.Domain;
import org.libreccm.categorization.DomainOwnership;
import org.libreccm.core.Resource; import org.libreccm.core.Resource;
import org.libreccm.core.Group; import org.libreccm.core.Group;
import org.libreccm.jpa.utils.UriConverter; import org.libreccm.jpa.utils.UriConverter;
import java.io.Serializable; import java.io.Serializable;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Convert; import javax.persistence.Convert;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/** /**
* *
@ -39,18 +50,34 @@ import javax.persistence.Table;
*/ */
@Entity @Entity
@Table(name = "applications") @Table(name = "applications")
@XmlRootElement(name = "application", namespace = WEB_XML_NS)
public class Application extends Resource implements Serializable { public class Application extends Resource implements Serializable {
private static final long serialVersionUID = 9205226362368890784L; private static final long serialVersionUID = 9205226362368890784L;
@Column(name = "primary_url", length = 1024, nullable = false) @Column(name = "primary_url", length = 1024, nullable = false)
@Convert(converter = UriConverter.class) @Convert(converter = UriConverter.class)
@XmlElement(name = "primary-url", namespace = WEB_XML_NS)
private URI primaryUrl; private URI primaryUrl;
@OneToOne @OneToOne
@JoinColumn(name = "container_group_id") @JoinColumn(name = "container_group_id")
@XmlElement(name = "container-group", namespace = WEB_XML_NS)
private Group containerGroup; private Group containerGroup;
/**
* Category Domains owned by this {@code CcmObject}.
*/
@OneToMany(mappedBy = "owner")
@XmlElementWrapper(name = "domains", namespace = WEB_XML_NS)
@XmlElement(name = "domain", namespace = WEB_XML_NS)
private List<DomainOwnership> domains;
public Application() {
super();
domains = new ArrayList<>();
}
public URI getPrimaryUrl() { public URI getPrimaryUrl() {
return primaryUrl; return primaryUrl;
} }
@ -67,6 +94,48 @@ public class Application extends Resource implements Serializable {
this.containerGroup = containerGroup; this.containerGroup = containerGroup;
} }
/**
* Gets an <strong>unmodifiable</strong> list of the domains which are owned
* by the {@code Application}.
*
* @return An unmodifiable list of the domain ownerships of this
* {@code Application}. Might be {@code null} or empty.
*/
public List<DomainOwnership> getDomains() {
return Collections.unmodifiableList(domains);
}
/**
* Setter for the list of domain ownerships, only for use by JPA.
*
* @param domains A list of domain ownerships.
*/
protected void setDomains(final List<DomainOwnership> domains) {
this.domains = domains;
}
/**
* <strong>Internal</strong> method for adding a domain ownership. Users
* should use the appropriate methods of the {@link DomainManager} class to
* manage the {@link Domain}s assigned to {@code CcmObject}.
*
* @param domain The domain ownership to add.
*/
protected void addDomain(final DomainOwnership domain) {
domains.add(domain);
}
/**
* <strong>Internal</strong> method for removing a domain ownership. Users
* should use the appropriate methods of the {@link DomainManager} to manage
* the {@link Domain}s assigned to {@code CcmObject}.
*
* @param domain The domain to remove.
*/
protected void removeDomain(final DomainOwnership domain) {
domains.remove(domain);
}
@Override @Override
public int hashCode() { public int hashCode() {
int hash = super.hashCode(); int hash = super.hashCode();
@ -99,7 +168,7 @@ public class Application extends Resource implements Serializable {
} }
return Objects.equals(containerGroup, other.getContainerGroup()); return Objects.equals(containerGroup, other.getContainerGroup());
} }
@Override @Override
public boolean canEqual(final Object obj) { public boolean canEqual(final Object obj) {
return obj instanceof Application; return obj instanceof Application;

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.web;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class WebConstants {
public static final String WEB_XML_NS = "http://web.libreccm.org";
private WebConstants() {
//Nothing
}
}

View File

@ -24,7 +24,10 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import org.libreccm.tests.categories.UnitTest; import org.libreccm.tests.categories.UnitTest;
import org.libreccm.web.Application;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -52,19 +55,25 @@ public class EqualsAndHashCodeTest {
} }
@Test @Test
public void verifyEqualsAndHashCode() { public void verifyEqualsAndHashCode() throws URISyntaxException {
final Category category1 = new Category(); final Category category1 = new Category();
category1.setName("Category One"); category1.setName("Category One");
final Category category2 = new Category(); final Category category2 = new Category();
category2.setName("Category Two"); category2.setName("Category Two");
final Domain domain1 = new Domain(); final Domain domain1 = new Domain();
domain1.setDomainKey("Domain-One"); domain1.setDomainKey("Domain-One");
final Domain domain2 = new Domain(); final Domain domain2 = new Domain();
domain2.setDomainKey("Domain Two"); domain2.setDomainKey("Domain Two");
final Application application1 = new Application();
application1.setPrimaryUrl(new URI("http://application-one.exampl.org"));
final Application application2 = new Application();
application2.setPrimaryUrl(new URI("http://application-two.exampl.org"));
EqualsVerifier EqualsVerifier
.forClass(entityClass) .forClass(entityClass)
.suppress(Warning.STRICT_INHERITANCE) .suppress(Warning.STRICT_INHERITANCE)
@ -72,6 +81,7 @@ public class EqualsAndHashCodeTest {
.withRedefinedSuperclass() .withRedefinedSuperclass()
.withPrefabValues(Category.class, category1, category2) .withPrefabValues(Category.class, category1, category2)
.withPrefabValues(Domain.class, domain1, domain2) .withPrefabValues(Domain.class, domain1, domain2)
.withPrefabValues(Application.class, application1, application2)
.verify(); .verify();
} }

View File

@ -106,6 +106,7 @@ public class CcmObjectRepositoryTest {
.create(WebArchive.class, .create(WebArchive.class,
"LibreCCM-org.libreccm.core.CcmObjectRepositoryTest.war"). "LibreCCM-org.libreccm.core.CcmObjectRepositoryTest.war").
addPackage(CcmObject.class.getPackage()) addPackage(CcmObject.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class. .addPackage(org.libreccm.categorization.Category.class.
getPackage()) getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()). .addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -29,9 +29,9 @@
<modules> <modules>
<module>ccm-core</module> <module>ccm-core</module>
<module>ccm-shortcuts</module> <module>ccm-shortcuts</module>
<module>ccm-testutils</module> <module>ccm-testutils</module>
</modules> </modules>
<repositories> <repositories>
<repository> <repository>