/*
* Permission.java
*
* Created on August 1, 2007, 10:03 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.auth.service.db;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import org.infoset.xml.Element;
import org.infoset.xml.ItemConstructor;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.XMLException;
import org.milowski.db.DBCache;
import org.milowski.db.DBConnection;
import org.milowski.db.DBIterator;
import org.milowski.db.DBObject;
import org.milowski.db.DBQueryHandler;
import org.milowski.db.DBResultConstructor;
import org.milowski.db.DBUpdateHandler;
import org.milowski.db.Slot;
/**
*
* @author alex
*/
public class Group extends DBObject<AuthDB> implements XMLObject
{
Realm realm;
String name;
UUID uuid;
Set<Role> roles;
/** Creates a new instance of Permission */
public Group(AuthDB db,int id,Realm realm,UUID uuid,String name)
throws SQLException
{
super(db,id);
this.realm = realm;
this.name = name;
this.uuid = uuid;
this.roles = new TreeSet<Role>();
init();
}
protected void init()
throws SQLException
{
DBConnection connection = db.getConnection();
try {
connection.query(AuthDB.GROUP_ROLES, new DBQueryHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1, id);
}
public void onResults(ResultSet set)
throws SQLException
{
while (set.next()) {
int gid = set.getInt(1);
Role role = db.roleCache.get(gid);
roles.add(role);
}
}
});
} finally {
db.release(connection);
}
}
public void delete()
throws SQLException
{
DBConnection connection = db.getConnection();
try {
connection.deleteById(AuthDB.DELETE_GROUP_MEMBERS, id);
connection.deleteById(AuthDB.DELETE_GROUP_ROLES, id);
connection.deleteById(AuthDB.DELETE_GROUP, id);
db.realmGroupCaches.get(realm).remove(id);
} finally {
db.release(connection);
}
}
public Realm getRealm() {
return realm;
}
public String getAlias()
{
return name;
}
public UUID getUUID()
{
return uuid;
}
public boolean addRole(final Role role)
throws SQLException
{
if (roles.contains(role)) {
return true;
}
DBConnection connection = db.getConnection();
try {
connection.update(AuthDB.CREATE_GROUP_ROLE, new DBUpdateHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1,id);
s.setInt(2,role.getId());
}
});
} finally {
db.release(connection);
}
roles.add(role);
return true;
}
public boolean removeRole(final Role role)
throws SQLException
{
DBConnection connection = db.getConnection();
try {
return connection.update(AuthDB.DELETE_GROUP_ROLE, new DBUpdateHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1,id);
s.setInt(2,role.getId());
}
})>0;
} finally {
db.release(connection);
}
}
public boolean hasRole(Role role)
{
return roles.contains(role);
}
public Iterator<Role> getRoles() {
return roles.iterator();
}
public boolean hasPermission(Permission permission)
throws SQLException
{
for (Role role : roles) {
if (role.hasPermission(permission)) {
return true;
}
}
return false;
}
public void addMember(final RealmUser user)
throws SQLException
{
DBConnection connection = db.getConnection();
try {
connection.update(AuthDB.CREATE_GROUP_MEMBER, new DBUpdateHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1,id);
s.setInt(2,user.getId());
}
});
} finally {
db.release(connection);
}
}
public boolean removeMember(final RealmUser user)
throws SQLException
{
DBConnection connection = db.getConnection();
try {
return connection.update(AuthDB.DELETE_GROUP_MEMBER, new DBUpdateHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1,id);
s.setInt(2,user.getId());
}
})>0;
} finally {
db.release(connection);
}
}
public boolean hasMember(final RealmUser user)
throws SQLException
{
final Slot<Boolean> member = new Slot<Boolean>(false);
DBConnection connection = db.getConnection();
try {
connection.query(AuthDB.GROUP_MEMBER, new DBQueryHandler() {
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1,id);
s.setInt(2,user.getId());
}
public void onResults(ResultSet set)
throws SQLException
{
member.set(set.next());
}
});
} finally {
db.release(connection);
}
return member.get();
}
public Iterator<RealmUser> getMembers()
throws SQLException
{
final Slot<Iterator<RealmUser>> result = new Slot<Iterator<RealmUser>>();
final DBCache<UUID,RealmUser> cache = db.realmUserCaches.get(realm);
final DBConnection connection = db.getConnection();
try {
connection.query(AuthDB.GROUP_MEMBERS, new DBQueryHandler() {
public boolean shouldClose() { return false; }
public void prepare(PreparedStatement s)
throws SQLException
{
s.setInt(1, id);
}
public void onResults(ResultSet set)
{
result.set(new DBIterator<RealmUser>(set,new DBResultConstructor<RealmUser>() {
public RealmUser newInstance(ResultSet set)
throws SQLException
{
return cache.get(set.getInt(1));
}
},db,connection));
}
});
} catch (SQLException ex) {
db.release(connection);
throw ex;
}
return result.get();
}
public void refresh()
throws SQLException
{
roles.clear();
init();
}
public boolean equals(Object obj) {
return obj instanceof Group && ((Group)obj).getUUID().equals(uuid);
}
public void generate(ItemConstructor constructor,ItemDestination dest)
throws XMLException
{
generate(constructor,dest,true);
}
public void generate(ItemConstructor constructor,ItemDestination dest,boolean contents)
throws XMLException
{
Element top = constructor.createElement(XML.GROUP_NAME);
top.setAttributeValue("id",uuid.toString());
top.setAttributeValue("alias",name);
top.setAttributeValue("realm",realm.getUUID().toString());
dest.send(top);
if (contents) {
dest.send(constructor.createCharacters("\n"));
dest.send(constructor.createElement(XML.ROLES_NAME));
boolean first = true;
for (Role r : roles) {
if (first) {
dest.send(constructor.createCharacters("\n"));
first = false;
}
r.generate(constructor,dest,false);
dest.send(constructor.createCharacters("\n"));
}
dest.send(constructor.createElementEnd(XML.ROLES_NAME));
dest.send(constructor.createCharacters("\n"));
dest.send(constructor.createElement(XML.USERS_NAME));
try {
first = true;
Iterator<RealmUser> users = getMembers();
while (users.hasNext()) {
if (first) {
dest.send(constructor.createCharacters("\n"));
first = false;
}
users.next().generate(constructor,dest);
dest.send(constructor.createCharacters("\n"));
}
} catch (SQLException ex) {
throw new XMLException("Cannot get member list for group.",ex);
}
dest.send(constructor.createElementEnd(XML.USERS_NAME));
dest.send(constructor.createCharacters("\n"));
}
dest.send(constructor.createElementEnd(XML.GROUP_NAME));
}
}