/*
* Group.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Copyright (c) 2004-2005 Per Cederberg. All rights reserved.
*/
package org.liquidsite.core.content;
import java.util.ArrayList;
import org.liquidsite.core.data.DataObjectException;
import org.liquidsite.core.data.DataSource;
import org.liquidsite.core.data.GroupData;
import org.liquidsite.core.data.GroupPeer;
import org.liquidsite.core.data.UserGroupData;
import org.liquidsite.core.data.UserGroupPeer;
import org.liquidsite.util.log.Log;
/**
* A system group.
*
* @author Per Cederberg, <per at percederberg dot net>
* @version 1.0
*/
public class Group extends PersistentObject {
/**
* The class logger.
*/
private static final Log LOG = new Log(Group.class);
/**
* The permitted group name characters.
*/
public static final String NAME_CHARS =
UPPER_CASE + LOWER_CASE + NUMBERS + BINDERS;
/**
* The group data.
*/
private GroupData data;
/**
* The list of user names added since the object was saved.
*/
private ArrayList usersAdded = null;
/**
* The list of user names removed since the object was saved.
*/
private ArrayList usersRemoved = null;
/**
* Returns a list of matching groups in a specified domain. Only
* groups with matching names will be returned.
*
* @param manager the content manager to use
* @param domain the domain
* @param filter the search filter (empty for all)
*
* @return an array of all groups in the domain
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
static Group[] findByDomain(ContentManager manager,
Domain domain,
String filter)
throws ContentException {
DataSource src = getDataSource(manager);
ArrayList list;
Group[] res;
try {
list = GroupPeer.doSelectByDomain(src, domain.getName(), filter);
res = new Group[list.size()];
for (int i = 0; i < list.size(); i++) {
res[i] = new Group(manager, (GroupData) list.get(i));
}
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
} finally {
src.close();
}
return res;
}
/**
* Returns a group with a specified name.
*
* @param manager the content manager to use
* @param domain the domain
* @param name the group name
*
* @return the group found, or
* null if no matching group existed
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
static Group findByName(ContentManager manager,
Domain domain,
String name)
throws ContentException {
DataSource src = getDataSource(manager);
GroupData data;
try {
data = GroupPeer.doSelectByName(src, domain.getName(), name);
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
} finally {
src.close();
}
if (data == null) {
return null;
} else {
return new Group(manager, data);
}
}
/**
* Returns an array of all groups a certain user belongs to.
*
* @param manager the content manager to use
* @param user the user
*
* @return an array of all groups the user belongs to
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
static Group[] findByUser(ContentManager manager, User user)
throws ContentException {
DataSource src = getDataSource(manager);
ArrayList list;
Group[] res;
UserGroupData data;
GroupData group;
String name;
try {
list = UserGroupPeer.doSelectByUser(src,
user.getDomainName(),
user.getName());
res = new Group[list.size()];
for (int i = 0; i < list.size(); i++) {
data = (UserGroupData) list.get(i);
name = data.getString(UserGroupData.GROUP);
group = GroupPeer.doSelectByName(src,
user.getDomainName(),
name);
res[i] = new Group(manager, group);
}
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
} finally {
src.close();
}
return res;
}
/**
* Creates a new group with default values.
*
* @param manager the content manager to use
* @param domain the domain
* @param name the group name
*/
public Group(ContentManager manager, Domain domain, String name) {
super(manager, false);
this.data = new GroupData();
this.data.setString(GroupData.DOMAIN, domain.getName());
this.data.setString(GroupData.NAME, name);
}
/**
* Creates a new group from a data object.
*
* @param manager the content manager to use
* @param data the group data object
*/
private Group(ContentManager manager, GroupData data) {
super(manager, true);
this.data = data;
}
/**
* Checks if this group equals another object. This method will
* only return true if the other object is a group with the same
* domain and group name.
*
* @param obj the object to compare with
*
* @return true if the other object is an identical group, or
* false otherwise
*/
public boolean equals(Object obj) {
if (obj instanceof Group) {
return equals((Group) obj);
} else {
return false;
}
}
/**
* Checks if this group equals another group. This method will
* only return true if the other object is a group with the same
* domain and group name.
*
* @param obj the object to compare with
*
* @return true if the other object is an identical group, or
* false otherwise
*/
public boolean equals(Group obj) {
return getDomainName().equals(obj.getDomainName())
&& getName().equals(obj.getName());
}
/**
* Returns a string representation of this object.
*
* @return a string representation of this object
*/
public String toString() {
return getName();
}
/**
* Returns the group domain.
*
* @return the group domain
*
* @throws ContentException if no content manager is available
*/
public Domain getDomain() throws ContentException {
return getContentManager().getDomain(getDomainName());
}
/**
* Returns the group domain name
*
* @return the group domain name
*/
public String getDomainName() {
return data.getString(GroupData.DOMAIN);
}
/**
* Returns the group name.
*
* @return the group name
*/
public String getName() {
return data.getString(GroupData.NAME);
}
/**
* Returns the group description.
*
* @return the group description
*/
public String getDescription() {
return data.getString(GroupData.DESCRIPTION);
}
/**
* Sets the the group description.
*
* @param description the new group description
*/
public void setDescription(String description) {
data.setString(GroupData.DESCRIPTION, description);
}
/**
* Checks if this group is public. A public group allows users
* to add or remove themselves to or from the group. This is used
* in the template API to allow users administer some of their
* group memberships. The public groups should not be security
* related, but only used for other things such as mailing list
* membership and similar.
*
* @return true if this group is public, or
* false otherwise
*/
public boolean isPublic() {
return data.getBoolean(GroupData.PUBLIC);
}
/**
* Sets the public group flag. A public group allows users to add
* or remove themselves to or from the group. This is used in the
* template API to allow users administer some of their group
* memberships. The public groups should not be security related,
* but only used for other things such as mailing list membership
* and similar.
*
* @param value the new flag value
*/
public void setPublic(boolean value) {
data.setBoolean(GroupData.PUBLIC, value);
}
/**
* Returns the group comment.
*
* @return the group comment
*/
public String getComment() {
return data.getString(GroupData.COMMENT);
}
/**
* Sets the group comment.
*
* @param comment the new group comment
*/
public void setComment(String comment) {
data.setString(GroupData.COMMENT, comment);
}
/**
* Returns the number of users that belong to this group. This
* method will only count the users registered to this group in
* the database.
*
* @return the number of users that belong to this group
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
public int getUserCount() throws ContentException {
return User.countByGroup(getContentManager(), this);
}
/**
* Returns the users that belong to this group. This method will
* only return the users registered to this group in the database.
* Also, only a limited interval of the matching users will be
* returned.
*
* @param startPos the list interval start position
* @param maxLength the list interval maximum length
*
* @return an array of users belonging to this group
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
public User[] getUsers(int startPos, int maxLength)
throws ContentException {
return User.findByGroup(getContentManager(),
this,
startPos,
maxLength);
}
/**
* Adds the specified user to this group. This action will not
* take effect until this object is saved.
*
* @param user the user object
*/
public void addUser(User user) {
if (getDomainName().equals(user.getDomainName())) {
if (usersAdded == null) {
usersAdded = new ArrayList();
}
usersAdded.add(user.getName());
}
}
/**
* Removes the specified user from this group. This action will
* not take effect until this object is saved.
*
* @param user the user object
*/
public void removeUser(User user) {
if (getDomainName().equals(user.getDomainName())) {
if (usersRemoved == null) {
usersRemoved = new ArrayList();
}
usersRemoved.add(user.getName());
}
}
/**
* Validates the object data before writing to the database.
*
* @throws ContentException if the object data wasn't valid
*/
protected void doValidate() throws ContentException {
ContentManager manager = getContentManager();
if (!isPersistent()) {
if (getDomainName().equals("")) {
throw new ContentException("no domain set for group object");
} else if (getDomain() == null) {
throw new ContentException("domain '" + getDomainName() +
"' does not exist");
}
validateSize("group name", getName(), 1, 30);
validateChars("group name", getName(), NAME_CHARS);
if (manager.getGroup(getDomain(), getName()) != null) {
throw new ContentException("group '" + getName() +
"' already exists");
}
}
validateSize("group description", getDescription(), 0, 100);
validateSize("group comment", getComment(), 0, 200);
}
/**
* Inserts the object data into the database. If the restore flag
* is set, no automatic changes should be made to the data before
* writing to the database.
*
* @param src the data source to use
* @param user the user performing the operation
* @param restore the restore flag
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
protected void doInsert(DataSource src, User user, boolean restore)
throws ContentException {
try {
GroupPeer.doInsert(src, data);
doUserGroups(src);
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
}
}
/**
* Updates the object data in the database.
*
* @param src the data source to use
* @param user the user performing the operation
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
protected void doUpdate(DataSource src, User user)
throws ContentException {
try {
GroupPeer.doUpdate(src, data);
doUserGroups(src);
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
}
}
/**
* Deletes the object data from the database.
*
* @param src the data source to use
* @param user the user performing the operation
*
* @throws ContentException if the database couldn't be accessed
* properly
*/
protected void doDelete(DataSource src, User user)
throws ContentException {
try {
GroupPeer.doDelete(src, data);
} catch (DataObjectException e) {
LOG.error(e.getMessage());
throw new ContentException(e);
}
}
/**
* Adds and removes user groups from the database.
*
* @param src the data source to use
*
* @throws DataObjectException if the data source couldn't be
* accessed properly
*/
private void doUserGroups(DataSource src)
throws DataObjectException {
UserGroupData userData;
// Handle added users
if (usersAdded != null) {
for (int i = 0; i < usersAdded.size(); i++) {
userData = new UserGroupData();
userData.setString(UserGroupData.DOMAIN, getDomainName());
userData.setString(UserGroupData.USER,
usersAdded.get(i).toString());
userData.setString(UserGroupData.GROUP, getName());
UserGroupPeer.doInsert(src, userData);
}
usersAdded = null;
}
// Handle removed users
if (usersRemoved != null) {
for (int i = 0; i < usersRemoved.size(); i++) {
userData = new UserGroupData();
userData.setString(UserGroupData.DOMAIN, getDomainName());
userData.setString(UserGroupData.USER,
usersRemoved.get(i).toString());
userData.setString(UserGroupData.GROUP, getName());
UserGroupPeer.doDelete(src, userData);
}
usersRemoved = null;
}
}
}