package de.circleofcontacts.server.dao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import de.circleofcontacts.client.view.ContactDetailView;
import de.circleofcontacts.client.view.ContactGroupSummaryView;
import de.circleofcontacts.client.view.ContactSummaryView;
import de.circleofcontacts.server.model.Contact;
import de.circleofcontacts.server.model.ContactGroup;
import de.circleofcontacts.server.model.Gender;
/**
* Database access object for contacts, contact groups, contact details.
* @author Matthias Wuttke
*/
public class ContactDao {
// ========================================================================
// CONTACT GROUPS
// ========================================================================
/**
* Loads a contact group by the given identifier.
* @param identifier contact group id
* @return contact group
*/
public ContactGroup getContactGroup(String identifier) {
return (ContactGroup)persistenceManager.getObjectById(ContactGroup.class, KeyFactory.stringToKey(identifier));
}
/**
* Retrieves a list of contact group view objects for the given user.
* @param userEmail email address of user
* @return contact group list
*/
public List<ContactGroupSummaryView> getContactGroups(String userEmail) {
Query query = persistenceManager.newQuery(ContactGroup.class);
query.setResult("groupId, label");
query.setFilter("owners.contains(emailParam) AND deleted = false");
query.declareParameters("String emailParam");
List<?> result = (List<?>)query.execute(userEmail);
List<ContactGroupSummaryView> result2 = new ArrayList<ContactGroupSummaryView>();
for (Object o : result) {
Object[] c = (Object[])o;
de.circleofcontacts.client.view.ContactGroupSummaryView cg = new de.circleofcontacts.client.view.ContactGroupSummaryView();
cg.setIdentifier(KeyFactory.keyToString((Key)c[0]));
cg.setLabel((String)c[1]);
result2.add(cg);
}
return result2;
}
/**
* Creates and saves a new contact group.
* @param userEmail e-mail of the first group owner
* @param label group name
* @return new group object
*/
public ContactGroup createContactGroup(String userEmail, String label) {
List<String> ownersList = new LinkedList<String>();
if (userEmail != null && userEmail.length() > 0)
ownersList.add(userEmail);
ContactGroup cg = new ContactGroup();
cg.setLabel(label);
cg.setDeleted(false);
cg.setOwners(ownersList);
persistenceManager.makePersistent(cg);
return cg;
}
/**
* Saves a new contact group or updates an existing contact group.
* @param contactGroup contact group view
* @param userEmail initial owner for new groups; may be null
* @return
*/
public String saveContactGroup(ContactGroupSummaryView contactGroup, String userEmail) {
if (contactGroup.getIdentifier() == null || contactGroup.getIdentifier().length() == 0) {
ContactGroup cg = createContactGroup(userEmail, contactGroup.getLabel());
return KeyFactory.keyToString(cg.getGroupId()); // o je, ist noch null
} else {
ContactGroup group = getContactGroup(contactGroup.getIdentifier());
group.setLabel(contactGroup.getLabel());
persistenceManager.makePersistent(group);
return contactGroup.getIdentifier();
}
}
/**
* Marks a contact group as deleted.
* @param groupId group ID
*/
public void deleteContactGroup(String groupId) {
ContactGroup group = getContactGroup(groupId);
group.setDeleted(true);
persistenceManager.makePersistent(group);
}
// ========================================================================
// CONTACT VIEWS
// ========================================================================
/**
* Retrieves a list of contact summary view objects for the
* given contact group.
* @param groupId contact group ID
* @return contact summary view objects
*/
@SuppressWarnings("unchecked")
public List<ContactSummaryView> getContactViewsByGroup(String groupId) {
ContactGroup cg = getContactGroup(groupId);
List<ContactSummaryView> result = new ArrayList<ContactSummaryView>();
Query q = persistenceManager.newQuery(Contact.class);
q.setFilter("groups.contains(:groupId)");
q.setResult("mainContactId, firstName, lastName, title, suffix, gender");
Collection<Object[]> summaries = (Collection<Object[]>)q.execute(cg.getGroupId());
for (Object[] summary : summaries) {
ContactSummaryView co = new ContactSummaryView();
co.setIdentifier(KeyFactory.keyToString((Key)summary[0]));
co.setFirstName((String)summary[1]);
co.setLastName((String)summary[2]);
co.setTitle((String)summary[3]);
co.setSuffix((String)summary[4]);
co.setGender((Gender)summary[5]);
result.add(co);
}
return result;
}
/**
* Retrieves a list of all contact views the given user may access.
* @param userEmail user email address
* @param query search query
* @return contact summary view objects
*/
public List<ContactSummaryView> getContactViewsByUser(String userEmail, String query) {
// TODO
return null;
}
/**
* Loads a backend contact object.
* @param contactId contact ID
* @return object
*/
private Contact getContact(String contactId) {
Query q = persistenceManager.newQuery(Contact.class);
q.setFilter("recent = true AND mainContactId = :mainContactId");
Collection<?> contacts = (Collection<?>)q.execute(KeyFactory.stringToKey(contactId));
return (Contact)contacts.iterator().next();
//(Contact)persistenceManager.getObjectById(Contact.class, KeyFactory.stringToKey(contactId));
}
/**
* Saves or updates a contact.
* @param basicData
* @return
*/
public String saveContact(ContactSummaryView basicData) {
if (basicData.getIdentifier() == null)
return saveNewContact(basicData);
else
return updateExistingContact(basicData);
}
/**
* Updates an existing contact.
* @param basicData contact data
* @return
*/
private String updateExistingContact(ContactSummaryView basicData) {
Contact prevContact = getContact(basicData.getIdentifier());
Contact newContact = prevContact.clone();
prevContact.setRecent(false);
persistenceManager.makePersistent(prevContact);
newContact.setVersion(prevContact.getVersion() + 1);
return KeyFactory.keyToString(persistenceManager.makePersistent(newContact).getKey());
}
/**
* Saves a new contact.
* @param basicData contact data
* @return
*/
private String saveNewContact(ContactSummaryView basicData) {
Contact c = new Contact();
c.setFirstName(basicData.getFirstName());
c.setLastName(basicData.getLastName());
c.setTitle(basicData.getTitle());
Key key = persistenceManager.makePersistent(c).getKey();
c.setMainContactId(key);
return KeyFactory.keyToString(key);
}
// ========================================================================
// CONTACT GROUP MEMBERSHIP
// ========================================================================
/**
* Adds the given contact to the given group.
* Loads both the contact and the group.
* @param contactId contact ID
* @param groupId group ID
*/
public void addContactToGroup(String contactId, String groupId) {
ContactGroup contactGroup = getContactGroup(groupId);
Contact contact = (Contact)persistenceManager.getObjectById(Contact.class, KeyFactory.stringToKey(contactId));
addContactToGroup(contact, contactGroup);
}
/**
* Adds the given contact to the given group.
* Checks if the contact is already group member.
*/
public void addContactToGroup(Contact contact, ContactGroup contactGroup) {
if (contact.getGroups() == null)
contact.setGroups(new LinkedList<Key>());
if (!contact.getGroups().contains(contactGroup.getGroupId()))
contact.getGroups().add(contactGroup.getGroupId());
persistenceManager.makePersistent(contact);
}
/**
* Removes the given contact from the given group.
* @param contactId contact ID
* @param groupId group ID
*/
public void removeContactFromGroup(String contactId, String groupId) {
ContactGroup contactGroup = getContactGroup(groupId);
Contact contact = getContact(contactId);
removeContactFromGroup(contact, contactGroup);
}
/**
* Removes the given contact from the given group.
* @param contact contact
* @param group group
*/
public void removeContactFromGroup(Contact contact, ContactGroup contactGroup) {
if (contact.getGroups() != null) {
contact.getGroups().remove(contactGroup.getGroupId());
persistenceManager.makePersistent(contact);
}
}
public String saveContactDetail(ContactDetailView detail) {
return null;
}
// ========================================================================
// MISC STUFF
// ========================================================================
/**
* Retrieves the persistence manager factory.
* @return persistence manager factory
*/
public static PersistenceManagerFactory getPersistanceManagerFactory() {
return pmfInstance;
}
/**
* Creates the singleton instance of the contact DAO.
*/
public ContactDao() {
persistenceManager = getPersistanceManagerFactory().getPersistenceManager();
}
/**
* Persistence manager
*/
private PersistenceManager persistenceManager;
/**
* Persistence manager factory
*/
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
}