/*
* Copyright (C) 2004 Red Hat Inc. All Rights Reserved.
*
* The contents of this file are subject to the Open Software License v2.1
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://rhea.redhat.com/licenses/osl2.1.html.
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
*/
package com.arsdigita.cms.contentassets;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.contenttypes.Link;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.mimetypes.MimeType;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.DataOperation;
import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.Filter;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.util.Assert;
import java.math.BigDecimal;
import org.apache.log4j.Logger;
/**
* This content type represents a Link content type for linking
* ContentItems and external links.
*
* @author Scott Seago (sseago@redhat.com)
* @version $Revision: #4 $ $Date: 2004/03/30 $
*/
public class RelatedLink extends Link {
private static final Logger s_log = Logger.getLogger(RelatedLink.class);
/** PDL properties */
public static final String LINK_LIST_NAME = "linkListName";
public static final String RESOURCE_SIZE = "resourceSize";
public static final String RESOURCE_TYPE = "resourceType";
public static final String LINK_OWNER = "linkOwner";
public static final String RELATED_LINKS = "links";
/** Data object type for this domain object */
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.cms.contentassets.RelatedLink";
/**
* Default constructor. This creates a new RelatedLink.
*/
public RelatedLink() {
this(BASE_DATA_OBJECT_TYPE);
}
/**
* Constructor. The contained DataObject is retrieved
* from the persistent storage mechanism with an OID
* specified by id and RelatedLink.BASE_DATA_OBJECT_TYPE.
*
* @param id The id for the retrieved
* DataObject
*/
public RelatedLink(BigDecimal id)
throws DataObjectNotFoundException {
this(new OID(BASE_DATA_OBJECT_TYPE, id));
}
/**
* Constructor. The contained DataObject is retrieved
* from the persistent storage mechanism with an OID
* specified by oid.
*
* @param oid The OID for the retrieved
* DataObject
*/
public RelatedLink(OID oid)
throws DataObjectNotFoundException {
super(oid);
}
/**
* Constructor. Retrieves or creates a content item using the
* DataObject argument.
*
* @param obj The DataObject with which to create or
* load a content item
*/
public RelatedLink(DataObject obj) {
super(obj);
}
/**
* Constructor. Creates a new RelatedLink using the given data
* object type.
*
* @param type The String data object type of the
* item to create
*/
public RelatedLink(String type) {
super(type);
}
/** get the name of the named link list. */
public String getLinkListName() {
return (String) get(LINK_LIST_NAME);
}
/** Set the name of the named link list. */
public void setLinkListName(String name) {
set(LINK_LIST_NAME, name);
}
/**
* Get the MimeType of the target resource to which this link points.
*
* @return MimeType of target resource.
*/
public MimeType getResourceType() {
DataObject obj = (DataObject) get(RESOURCE_TYPE);
if (obj != null) {
return new MimeType(obj);
}
return null;
}
/**
* Set the MimeType of the target resource to which this link points.
*
* @param type , MimeType of target resource.
*/
public void setResourceType(MimeType type) {
setAssociation(RESOURCE_TYPE, type);
}
/** get the size of the target resource. */
public String getResourceSize() {
return (String) get(RESOURCE_SIZE);
}
/** Set the size of the target resource. */
public void setResourceSize(String size) {
set(RESOURCE_SIZE, size);
}
/**
* Sets the ContentItem that this link belongs to
*
* @param item The link Owner
*/
public void setLinkOwner(ContentItem item) {
Assert.exists(item, ContentItem.class);
s_log.debug("Setting linkOwner to" + item.getName());
setAssociation(LINK_OWNER, item);
}
/**
* Gets the ContentItem that this link belongs to
*
* @return The link Owner
*/
public ContentItem getLinkOwner() {
DataObject dobj = (DataObject) get(LINK_OWNER);
if (dobj == null) {
return null;
} else {
return (ContentItem) DomainObjectFactory.newInstance(dobj);
}
}
/**
* Convenient (compatiblility) method to retrieve related links for a
* given content item without a specific name for the link list).
*
* @param item The item to return links for
* @param name Name of the link list
* @return
*/
public static DataCollection getRelatedLinks(ContentItem item) {
return getRelatedLinks(item,"NONE");
}
/**
* Retrieves related links for a given content item
*
* @param item The item to return links for
* @param name Name of the link list
* @return
*/
public static DataCollection getRelatedLinks(ContentItem item, String name) {
s_log.debug(String.format("Getting related links for content item %s",
item.getID()));
long now = System.currentTimeMillis();
s_log.debug(String.format("Started at %d", now));
Session session = SessionManager.getSession();
DataCollection links = session.retrieve(BASE_DATA_OBJECT_TYPE);
links.addEqualsFilter(LINK_OWNER + ".id", item.getID());
links.addEqualsFilter(LINK_LIST_NAME, name);
links.addOrder(ORDER);
s_log.debug(String.format(
"Got all related links for content item %s in %d ms. (time finished: %d)",
item.getID().toString(),
System.currentTimeMillis() - now,
System.currentTimeMillis()));
return links;
}
/**
* Returns a DataCollection of related links which refer to the
* given item.
*
* @param item The target Item to return links for
*
* @return DataCollection of referring RelatedLinks
*/
public static DataCollection getReferringRelatedLinks(ContentItem item) {
Session session = SessionManager.getSession();
DataCollection links = session.retrieve(BASE_DATA_OBJECT_TYPE);
Filter filter =
links.addInSubqueryFilter("id",
"com.arsdigita.cms.contentassets.getReferringRelatedLinks");
filter.set("itemID", item.getID());
return links;
}
/**
* Swaps this RelatedLink with the next one,
* according to the linkOrder
*/
@Override
public void swapWithNext() {
swapWithNext(
"com.arsdigita.cms.contentassets.allRelatedLinkOrderForItem",
"com.arsdigita.cms.contentassets.swapRelatedLinkWithNextInGroup",
this.getLinkListName());
normalizeOrder();
}
/**
* Swaps this RelatedLink with the previous one,
* according to the linkOrder
*/
@Override
public void swapWithPrevious() {
swapWithPrevious(
"com.arsdigita.cms.contentassets.allRelatedLinkOrderForItem",
"com.arsdigita.cms.contentassets.swapRelatedLinkWithNextInGroup",
this.getLinkListName());
normalizeOrder();
}
/**
* Given a dataquery name, returns the (possibly filtered)
* DataQuery for use in swapKeys. This implementation filters
* on the linkOwner property, so that only
* RelatedLinks which belong to the same ContentItem
* will be swapped.
*
* @param queryName name of the DataQuery to use
* @return the DataQuery
*/
@Override
protected DataQuery getSwapQuery(String queryName) {
DataQuery query = super.getSwapQuery(queryName);
query.setParameter("ownerID", getLinkOwner().getID());
return query;
}
/**
* Given a data operation name, returns the
* DataOperation for use in swapKeys. This implementation sets the
* "ownerID" parameter, in addition to what is set by
* super.getSwapOperation
*
* @param operationName the Name of the DataOperation to use
*
* @return the DataOperation used to swap the sort keys.
*/
@Override
protected DataOperation getSwapOperation(String operationName) {
DataOperation operation = super.getSwapOperation(operationName);
operation.setParameter("ownerID", getLinkOwner().getID());
return operation;
}
/**
* This method is only used for setting initial sort keys for
* links which exist without them. This is called by swapKeys
* instead of attempting to swap if the key found is
* null. This implementation sorts all RelatedLinks owned by this
* RelatedLink's "linkOwner" by title.
*/
@Override
protected void alphabetize() {
Session session = SessionManager.getSession();
DataCollection links = session.retrieve(BASE_DATA_OBJECT_TYPE);
links.addEqualsFilter(LINK_OWNER + ".id", getLinkOwner().getID());
links.addEqualsFilter(LINK_LIST_NAME, getLinkListName());
links.addOrder(TITLE);
int sortKey = 0;
while (links.next()) {
sortKey++;
Link link = new RelatedLink(links.getDataObject());
link.setOrder(sortKey);
link.save();
}
}
/**
* This method normalizes the order column of the related links of this
* item. This means that the order column of the first related link will
* have the value 1 after calling this method, and so one.
*/
private void normalizeOrder() {
final DataCollection relatedLinks = getRelatedLinks(getLinkOwner(),
getLinkListName());
int i = 1;
while(relatedLinks.next()) {
relatedLinks.getDataObject().set(ORDER, i);
relatedLinks.getDataObject().save();
i++;
}
}
/**
* Returns the max sort key value for all RelatedLinks with the
* same link owner as this link.
*
* @return the max sort key value
*/
public int maxOrder() {
ContentItem linkOwner = getLinkOwner();
if (linkOwner == null) {
return 0;
}
int returnOrder = 0;
DataQuery query = SessionManager.getSession().retrieveQuery(
"com.arsdigita.cms.contentassets.allRelatedLinkOrderForItem");
query.setParameter("ownerID", getLinkOwner().getID());
query.setParameter("linkListName", getLinkListName());
query.addOrder("linkOrder DESC");
if (query.next()) {
Integer linkOrder = ((Integer) query.get("linkOrder"));
query.close();
if (linkOrder != null) {
returnOrder = linkOrder.intValue();
}
}
return returnOrder;
}
@Override
public void beforeSave() {
super.beforeSave();
if (getOrder() == null) {
setOrder(maxOrder() + 1);
}
}
}