BaseTypes

* XML-Dateien hinzugefügt, damit die BaseTypes in die Tabelle content_types geladen werden und als interne Typen gekennzeichnet sind
 * Euinige Fehlerkorrekturen an den UIs

ContentTypes
 * Klasse ContentType und Tabelle content_types erweitert um Felder für ancestors und siblings um die Vererbungshierachie speichern zu können
 * AbstractContentTypeLoader um Methode createPedigree erweitert, die aus der Verebungsstruktur der Klassen die Hierarchie ableitet und in der Datenbank speichert
 * ItemSerachWidget angepaßt, so daß es nun auch abgeleitete Contenttypen akzeptiert. Es werden nun z.B. auch CT's von Type contenttypes.Member angezeigt und als Zuweisung akzeptiert, wenn nach dem Vaterobject basetypes.Person verlangt wird.

git-svn-id: https://svn.libreccm.org/ccm/trunk@438 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2010-05-26 06:32:29 +00:00
parent e179fc9d30
commit 7e89a378fa
20 changed files with 1067 additions and 664 deletions

View File

@ -27,6 +27,11 @@ object type ContentType extends ACSObject {
String[1..1] label = content_types.label VARCHAR(1000); String[1..1] label = content_types.label VARCHAR(1000);
String[0..1] description = content_types.description VARCHAR(4000); String[0..1] description = content_types.description VARCHAR(4000);
String[0..1] className = content_types.classname VARCHAR(200); String[0..1] className = content_types.classname VARCHAR(200);
// Quasimodo: Store the information about ancenstors and siblings, so we
// can make use of extending content types
String[0..1] ancestors = content_types.ancestors VARCHAR(2000);
String[0..1] siblings = content_types.siblings VARCHAR(2000);
Boolean[1..1] isInternal = content_types.is_internal CHAR(1); Boolean[1..1] isInternal = content_types.is_internal CHAR(1);
BigDecimal[0..1] itemFormID = content_types.item_form_id INTEGER; BigDecimal[0..1] itemFormID = content_types.item_form_id INTEGER;
AuthoringKit[0..1] authoringKit = join content_types.type_id AuthoringKit[0..1] authoringKit = join content_types.type_id
@ -59,7 +64,7 @@ association {
do { do {
select select
t.type_id, t.object_type, t.label, t.description, t.classname, t.type_id, t.object_type, t.label, t.description, t.classname,
t.is_internal, t.item_form_id t.ancestors, t.siblings, t.is_internal, t.item_form_id
from from
content_types t, content_section_type_map m, authoring_kits a content_types t, content_section_type_map m, authoring_kits a
where where
@ -73,6 +78,8 @@ association {
creatableContentTypes.label = t.label; creatableContentTypes.label = t.label;
creatableContentTypes.description = t.description; creatableContentTypes.description = t.description;
creatableContentTypes.className = t.classname; creatableContentTypes.className = t.classname;
creatableContentTypes.ancestors = t.ancestors;
creatableContentTypes.siblings = t.siblings;
creatableContentTypes.isInternal = t.is_internal; creatableContentTypes.isInternal = t.is_internal;
creatableContentTypes.itemFormID = t.item_form_id; creatableContentTypes.itemFormID = t.item_form_id;
} }
@ -105,7 +112,7 @@ association {
do { do {
select select
t.type_id, t.object_type, t.label, t.description, t.classname, t.type_id, t.object_type, t.label, t.description, t.classname,
t.is_internal, t.item_form_id t.ancestors, t.siblings, t.is_internal, t.item_form_id
from from
content_types t content_types t
where where
@ -119,6 +126,8 @@ association {
notAssociatedContentTypes.label = t.label; notAssociatedContentTypes.label = t.label;
notAssociatedContentTypes.description = t.description; notAssociatedContentTypes.description = t.description;
notAssociatedContentTypes.className = t.classname; notAssociatedContentTypes.className = t.classname;
notAssociatedContentTypes.ancestors = t.ancestors;
notAssociatedContentTypes.siblings = t.siblings;
notAssociatedContentTypes.isInternal = t.is_internal; notAssociatedContentTypes.isInternal = t.is_internal;
notAssociatedContentTypes.itemFormID = t.item_form_id; notAssociatedContentTypes.itemFormID = t.item_form_id;
} }
@ -147,7 +156,8 @@ query registeredContentTypes {
do { do {
select select
t.type_id, t.object_type, t.label, t.type_id, t.object_type, t.label,
t.description, t.classname, t.is_internal, t.item_form_id t.description, t.classname, t.ancestors, t.siblings,
t.is_internal, t.item_form_id
from content_types t from content_types t
where t.is_internal = '0' where t.is_internal = '0'
and exists (select 1 from content_section_type_map and exists (select 1 from content_section_type_map
@ -158,6 +168,8 @@ query registeredContentTypes {
type.label = t.label; type.label = t.label;
type.description = t.description; type.description = t.description;
type.className = t.classname; type.className = t.classname;
type.ancestors = t.ancestors;
type.siblings = t.siblings;
type.isInternal = t.is_internal; type.isInternal = t.is_internal;
type.itemFormID = t.item_form_id; type.itemFormID = t.item_form_id;
} }

View File

@ -29,6 +29,8 @@ create table content_types (
label varchar(1000) not null, label varchar(1000) not null,
description varchar(4000), description varchar(4000),
classname varchar(200), classname varchar(200),
ancestors varchar(2000),
siblings varchar(2000),
is_internal char(1) default '0' not null is_internal char(1) default '0' not null
constraint content_types_is_internal_ck constraint content_types_is_internal_ck
check ( is_internal in ('0', '1') ), check ( is_internal in ('0', '1') ),

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<ctd:content-types xmlns:ctd="http://xmlns.redhat.com/cms/content-types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.redhat.com/cms/content-types content-types.xsd">
<ctd:content-type
label="Address"
description="A basic address type"
objectType="com.arsdigita.cms.basetypes.Address"
classname="com.arsdigita.cms.basetypes.Address"
isInternal="yes">
<ctd:authoring-kit
createComponent="com.arsdigita.cms.ui.authoring.PageCreate">
<ctd:authoring-step
labelKey="cms.contenttypes.shared.basic_properties.title"
labelBundle="com.arsdigita.cms.ui.CMSResources"
descriptionKey="cms.contenttypes.shared.basic_properties.description"
descriptionBundle="com.arsdigita.cms.ui.CMSResources"
component="com.arsdigita.cms.basetypes.ui.AddressPropertiesStep"
ordering="1"/>
<ctd:include href="/WEB-INF/content-types/assign-categories-step.xml"/>
</ctd:authoring-kit>
</ctd:content-type>
</ctd:content-types>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<ctd:content-types xmlns:ctd="http://xmlns.redhat.com/cms/content-types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.redhat.com/cms/content-types content-types.xsd">
<ctd:content-type
label="Article"
description="A basic article type"
objectType="com.arsdigita.cms.basetypes.Article"
classname="com.arsdigita.cms.basetypes.Article"
isInternal="yes">
</ctd:content-type>
</ctd:content-types>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<ctd:content-types xmlns:ctd="http://xmlns.redhat.com/cms/content-types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.redhat.com/cms/content-types content-types.xsd">
<ctd:content-type
label="Contact"
description="A basic Contact type"
objectType="com.arsdigita.cms.basetypes.Contact"
classname="com.arsdigita.cms.basetypes.Contact"
isInternal="yes">
<ctd:authoring-kit
createComponent="com.arsdigita.cms.ui.authoring.PageCreate">
<ctd:authoring-step
labelKey="cms.contenttypes.shared.basic_properties.title"
labelBundle="com.arsdigita.cms.ui.CMSResources"
descriptionKey="cms.contenttypes.shared.basic_properties.description"
descriptionBundle="com.arsdigita.cms.ui.CMSResources"
component="com.arsdigita.cms.basetypes.ui.ContactPropertiesStep"
ordering="1"/>
<ctd:include href="/WEB-INF/content-types/assign-categories-step.xml"/>
</ctd:authoring-kit>
</ctd:content-type>
</ctd:content-types>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<ctd:content-types xmlns:ctd="http://xmlns.redhat.com/cms/content-types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.redhat.com/cms/content-types content-types.xsd">
<ctd:content-type
label="Person"
description="A basic Person type"
objectType="com.arsdigita.cms.basetypes.Person"
classname="com.arsdigita.cms.basetypes.Person"
isInternal="yes">
<ctd:authoring-kit
createComponent="com.arsdigita.cms.ui.authoring.PageCreate">
<ctd:authoring-step
labelKey="cms.contenttypes.shared.basic_properties.title"
labelBundle="com.arsdigita.cms.ui.CMSResources"
descriptionKey="cms.contenttypes.shared.basic_properties.description"
descriptionBundle="com.arsdigita.cms.ui.CMSResources"
component="com.arsdigita.cms.basetypes.ui.PersonPropertiesStep"
ordering="1"/>
<ctd:include href="/WEB-INF/content-types/assign-categories-step.xml"/>
</ctd:authoring-kit>
</ctd:content-type>
</ctd:content-types>

View File

@ -387,7 +387,7 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
* override this method to return the correct value * override this method to return the correct value
*/ */
public String getBaseDataObjectType() { public String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE; return this.BASE_DATA_OBJECT_TYPE;
} }
/** /**
@ -553,6 +553,18 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
m_reporter.mutated("contentType"); m_reporter.mutated("contentType");
} }
public boolean isContentType(ContentType type) {
try {
// Try to cast this contentItem to the desired content type
// This will succeed if this ci is of the type or a subclass
Class.forName(type.getClassName()).cast(this);
return true;
} catch (Exception ex) {
return false;
}
}
/** /**
* Returns the content section to which this item belongs. * Returns the content section to which this item belongs.
* Fetches the denormalized content section of an item. If one is * Fetches the denormalized content section of an item. If one is
@ -684,14 +696,6 @@ public class ContentItem extends VersionedACSObject implements CustomCopy {
} }
} }
//add filter for ancestor check
int iLength;
if (includeSelf) {
iLength = ids.length();
} else {
iLength = ids.length() - 1;
}
//add list of ancestors split by "/" character //add list of ancestors split by "/" character
ArrayList ancestors = new ArrayList(); ArrayList ancestors = new ArrayList();
int iIndex = 0; int iIndex = 0;

View File

@ -58,7 +58,6 @@ public class ContentType extends ACSObject {
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.cms.ContentType"; "com.arsdigita.cms.ContentType";
public static final String OBJECT_TYPE = "associatedObjectType"; public static final String OBJECT_TYPE = "associatedObjectType";
public static final String LABEL = "label"; public static final String LABEL = "label";
public static final String DESCRIPTION = "description"; public static final String DESCRIPTION = "description";
@ -67,6 +66,8 @@ public class ContentType extends ACSObject {
public static final String AUTHORING_KIT = "authoringKit"; public static final String AUTHORING_KIT = "authoringKit";
public static final String ITEM_FORM_ID = "itemFormID"; public static final String ITEM_FORM_ID = "itemFormID";
public static final String ITEM_FORM = "itemForm"; public static final String ITEM_FORM = "itemForm";
public static final String ANCESTORS = "ancestors";
public static final String SIBLINGS = "siblings";
/** /**
* Default constructor. This creates a new folder. * Default constructor. This creates a new folder.
@ -112,10 +113,12 @@ public class ContentType extends ACSObject {
* @return the base PDL object type for this item. Child classes should * @return the base PDL object type for this item. Child classes should
* override this method to return the correct value * override this method to return the correct value
*/ */
@Override
public String getBaseDataObjectType() { public String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE; return BASE_DATA_OBJECT_TYPE;
} }
@Override
protected void beforeSave() { protected void beforeSave() {
if (isInternal() == null) { if (isInternal() == null) {
setInternal(false); setInternal(false);
@ -144,7 +147,6 @@ public class ContentType extends ACSObject {
set(OBJECT_TYPE, objType); set(OBJECT_TYPE, objType);
} }
/** /**
* Fetches the label for the content type. * Fetches the label for the content type.
* *
@ -317,12 +319,132 @@ public class ContentType extends ACSObject {
} }
/**
* Add an ancestor to the list of siblings, if not already in the list
* @param newAncestor ID of the ancestor to add
*/
public void addAncestor(BigDecimal newAncestor) {
// Get the list of siblings from db
String ancestors = (String) get(ANCESTORS);
// Only add if the newSibling in not yet in the list
if (ancestors == null) {
ancestors = newAncestor.toString();
} else if (!ancestors.contains(newAncestor.toString())) {
if (ancestors.length() == 0) {
// First entry in list
ancestors = newAncestor.toString();
} else {
// Additional entry in the list
ancestors += "/" + newAncestor.toString();
}
}
// Write new data back to db
set(ANCESTORS, ancestors);
}
/**
* Remove an ancestor id from the list of siblings
* @param ancestor ID to be removed
*/
public void delAncestor(BigDecimal ancestor) {
// Get the list of siblings from db
String ancestors = (String) get(ANCESTORS);
// Only try to remove from a non-empty string
if (ancestors != null && ancestors.length() > 0) {
// Remove ancestor ID from list
ancestors.replace(ancestor.toString(), "");
// Delete the additional slash
ancestors.replace("//", "/");
// If the list only contains a single slash,
// we have just removed the last list entry, so the list is empty
if (ancestors.equals("/")) {
ancestors = "";
}
}
// Write new data back to db
set(ANCESTORS, ancestors);
}
/**
* Get the list of ancestors
* @return
*/
public String getAncestors() {
return (String) get(ANCESTORS);
}
/**
* Add a sibling to the list of siblings, if not already in list
* @param newSibling ID of the sibling to add
*/
public void addSiblings(BigDecimal newSibling) {
// Get the list of siblings from db
String siblings = (String) get(SIBLINGS);
// Only add if the newSibling in not yet in the list
if (siblings == null) {
siblings = newSibling.toString();
} else if (!siblings.contains(newSibling.toString())) {
if (siblings.length() == 0) {
// First entry in list
siblings = newSibling.toString();
} else {
// Additional entry in the list
siblings += "/" + newSibling.toString();
}
}
// Write new data back to db
set(SIBLINGS, siblings);
}
/**
* Get the list of siblings
* @return
*/
public String getSiblings() {
return (String) get(SIBLINGS);
}
/**
* Remove a sibling from the list of siblings
* @param sibling ID to be removed
*/
public void delSiblings(BigDecimal sibling) {
// Get the list of siblings from db
String siblings = (String) get(SIBLINGS);
// Only try to remove from a non-empty string
if (siblings != null && siblings.length() > 0) {
// Remove ancestor ID from list
siblings.replace(sibling.toString(), "");
// Delete the additional slash
siblings.replace("//", "/");
// If the list only contains a single slash,
// we have just removed the last list entry, so the list is empty
if (siblings.equals("/")) {
siblings = "";
}
}
// Write new data back to db
set(SIBLINGS, siblings);
}
////////////////////////////////////// //////////////////////////////////////
// //
// Fetching/Finding content types. // Fetching/Finding content types.
// //
/** /**
* Find the content type with the associated with the object type. * Find the content type with the associated with the object type.
* *
@ -335,15 +457,35 @@ public class ContentType extends ACSObject {
ContentTypeCollection types = getAllContentTypes(); ContentTypeCollection types = getAllContentTypes();
types.addFilter("associatedObjectType = :type").set("type", objType); types.addFilter("associatedObjectType = :type").set("type", objType);
if (types.next()) { if (types.next()) {
ContentType type = types.getContentType(); ContentType type = types.getContentType();
types.close(); types.close();
return type; return type;
} else { } else {
// no match // no match
types.close(); types.close();
throw new DataObjectNotFoundException( throw new DataObjectNotFoundException(
"No matching content type for object type " + objType); "No matching content type for object type " + objType);
} }
} }
@ -355,6 +497,10 @@ public class ContentType extends ACSObject {
*/ */
public static ContentTypeCollection getAllContentTypes() { public static ContentTypeCollection getAllContentTypes() {
return getAllContentTypes(true); return getAllContentTypes(true);
} }
/** /**
@ -364,6 +510,10 @@ public class ContentType extends ACSObject {
*/ */
public static ContentTypeCollection getUserDefinedContentTypes() { public static ContentTypeCollection getUserDefinedContentTypes() {
return getAllContentTypes(false); return getAllContentTypes(false);
} }
/** /**
@ -371,13 +521,24 @@ public class ContentType extends ACSObject {
* content types. If false, only fetch all user-defined content types. * content types. If false, only fetch all user-defined content types.
*/ */
private static ContentTypeCollection getAllContentTypes(boolean internal) { private static ContentTypeCollection getAllContentTypes(boolean internal) {
DataCollection da = SessionManager.getSession().retrieve DataCollection da = SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
(BASE_DATA_OBJECT_TYPE);
ContentTypeCollection types = new ContentTypeCollection(da); ContentTypeCollection types = new ContentTypeCollection(da);
if (!internal) { if (!internal) {
types.addFilter("isInternal = '0'"); types.addFilter("isInternal = '0'");
} }
return types; return types;
} }
/** /**
@ -390,13 +551,18 @@ public class ContentType extends ACSObject {
final String query = "com.arsdigita.cms.registeredContentTypes"; final String query = "com.arsdigita.cms.registeredContentTypes";
DataQuery dq = SessionManager.getSession().retrieveQuery(query); DataQuery dq = SessionManager.getSession().retrieveQuery(query);
DataCollection dc = new DataQueryDataCollectionAdapter(dq, "type"); DataCollection dc = new DataQueryDataCollectionAdapter(dq, "type");
return new ContentTypeCollection(dc); return new ContentTypeCollection(dc);
} }
private static List s_xsl = new ArrayList(); private static List s_xsl = new ArrayList();
/** /**
* NB this interface is liable to change. * NB this interface is liable to change.
* *
@ -407,6 +573,10 @@ public class ContentType extends ACSObject {
public static void registerXSLFile(ContentType type, public static void registerXSLFile(ContentType type,
String path) { String path) {
s_xsl.add(new XSLEntry(type, path)); s_xsl.add(new XSLEntry(type, path));
} }
/** /**
@ -419,6 +589,10 @@ public class ContentType extends ACSObject {
public static void unregisterXSLFile(ContentType type, public static void unregisterXSLFile(ContentType type,
String path) { String path) {
s_xsl.remove(new XSLEntry(type, path)); s_xsl.remove(new XSLEntry(type, path));
} }
/** /**
@ -427,9 +601,26 @@ public class ContentType extends ACSObject {
*/ */
public static Iterator getXSLFileURLs() { public static Iterator getXSLFileURLs() {
return new EntryIterator(s_xsl.iterator()); return new EntryIterator(s_xsl.iterator());
} }
private static class EntryIterator implements Iterator { private static class EntryIterator implements Iterator {
private Iterator m_inner; private Iterator m_inner;
public EntryIterator(Iterator inner) { public EntryIterator(Iterator inner) {
@ -460,6 +651,7 @@ public class ContentType extends ACSObject {
} }
private static class XSLEntry { private static class XSLEntry {
private ContentType m_type; private ContentType m_type;
private String m_path; private String m_path;
@ -477,15 +669,17 @@ public class ContentType extends ACSObject {
return m_path; return m_path;
} }
@Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof XSLEntry)) { if (!(o instanceof XSLEntry)) {
return false; return false;
} }
XSLEntry e = (XSLEntry) o; XSLEntry e = (XSLEntry) o;
return m_path.equals(e.m_path) && return m_path.equals(e.m_path)
m_type.equals(e.m_type); && m_type.equals(e.m_type);
} }
@Override
public int hashCode() { public int hashCode() {
return m_path.hashCode() + m_type.hashCode(); return m_path.hashCode() + m_type.hashCode();
} }

View File

@ -58,8 +58,8 @@ public class AddressPropertiesStep extends SimpleEditStep {
public static Component getAddressPropertySheet(ItemSelectionModel itemModel) { public static Component getAddressPropertySheet(ItemSelectionModel itemModel) {
DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel); DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.name").localize(), Address.NAME); sheet.add((String) GlobalizationUtil.globalize("cms.contenttypes.ui.name").localize(), Address.NAME);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.title").localize(), Address.TITLE); sheet.add((String) GlobalizationUtil.globalize("cms.contenttypes.ui.title").localize(), Address.TITLE);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.address").localize(), Address.ADDRESS); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.address").localize(), Address.ADDRESS);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.postal_code").localize(), Address.POSTAL_CODE); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.postal_code").localize(), Address.POSTAL_CODE);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.city").localize(), Address.CITY); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.city").localize(), Address.CITY);

View File

@ -73,17 +73,17 @@ public class ContactAddressPropertiesStep extends SimpleEditStep {
DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel); DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel);
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.baseAddress.address").localize(), "address." + Address.ADDRESS); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.address").localize(), "address." + Address.ADDRESS);
if (!Contact.getConfig().getHideAddressPostalCode()) { if (!Contact.getConfig().getHideAddressPostalCode()) {
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.baseAddress.postal_code").localize(), "address." + Address.POSTAL_CODE); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.postal_code").localize(), "address." + Address.POSTAL_CODE);
} }
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.baseAddress.city").localize(), "address." + Address.CITY); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.city").localize(), "address." + Address.CITY);
if (!Contact.getConfig().getHideAddressState()) { if (!Contact.getConfig().getHideAddressState()) {
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.baseAddress.state").localize(), "address." + Address.STATE); sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.state").localize(), "address." + Address.STATE);
} }
if (!Contact.getConfig().getHideAddressCountry()) { if (!Contact.getConfig().getHideAddressCountry()) {
sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.baseAddress.iso_country_code").localize(), sheet.add((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.iso_country_code").localize(),
"address." + Address.ISO_COUNTRY_CODE, "address." + Address.ISO_COUNTRY_CODE,
new DomainObjectPropertySheet.AttributeFormatter() { new DomainObjectPropertySheet.AttributeFormatter() {

View File

@ -79,7 +79,7 @@ public class ContactAttachAddressPropertyForm extends BasicPageForm implements F
@Override @Override
public void addWidgets() { public void addWidgets() {
add(new Label((String)BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.contact.select_address").localize())); add(new Label((String)BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.contact.select_address").localize()));
this.m_itemSearch = new ItemSearchWidget(ITEM_SEARCH, ContentType.findByAssociatedObjectType("com.arsdigita.cms.basetypes.BaseAddress")); this.m_itemSearch = new ItemSearchWidget(ITEM_SEARCH, ContentType.findByAssociatedObjectType("com.arsdigita.cms.basetypes.Address"));
add(this.m_itemSearch); add(this.m_itemSearch);
} }

View File

@ -6,7 +6,6 @@
* To change this template, choose Tools | Template Manager * To change this template, choose Tools | Template Manager
* and open the template in the editor. * and open the template in the editor.
*/ */
package com.arsdigita.cms.basetypes.ui; package com.arsdigita.cms.basetypes.ui;
import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormData;
@ -45,15 +44,12 @@ import org.apache.log4j.Logger;
public class ContactEditAddressPropertyForm extends BasicPageForm implements FormProcessListener, FormInitListener, FormSubmissionListener { public class ContactEditAddressPropertyForm extends BasicPageForm implements FormProcessListener, FormInitListener, FormSubmissionListener {
private static final Logger logger = Logger.getLogger(ContactPropertyForm.class); private static final Logger logger = Logger.getLogger(ContactPropertyForm.class);
private ContactAddressPropertiesStep m_step; private ContactAddressPropertiesStep m_step;
public static final String ADDRESS = Address.ADDRESS; public static final String ADDRESS = Address.ADDRESS;
public static final String POSTAL_CODE = Address.POSTAL_CODE; public static final String POSTAL_CODE = Address.POSTAL_CODE;
public static final String CITY = Address.CITY; public static final String CITY = Address.CITY;
public static final String STATE = Address.STATE; public static final String STATE = Address.STATE;
public static final String ISO_COUNTRY_CODE = Address.ISO_COUNTRY_CODE; public static final String ISO_COUNTRY_CODE = Address.ISO_COUNTRY_CODE;
/** /**
* ID of the form * ID of the form
*/ */
@ -128,6 +124,7 @@ public class ContactEditAddressPropertyForm extends BasicPageForm implements For
country.addValidationListener( country.addValidationListener(
new ParameterListener() { new ParameterListener() {
public void validate(ParameterEvent e) throws FormProcessException { public void validate(ParameterEvent e) throws FormProcessException {
ParameterData data = e.getParameterData(); ParameterData data = e.getParameterData();
String isoCode = (String) data.getValue(); String isoCode = (String) data.getValue();
@ -135,8 +132,7 @@ public class ContactEditAddressPropertyForm extends BasicPageForm implements For
data.addError((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.error_iso_country").localize()); data.addError((String) BasetypesGlobalizationUtil.globalize("cms.basetypes.ui.address.error_iso_country").localize());
} }
} }
} });
);
add(country); add(country);
} }
@ -160,8 +156,8 @@ public class ContactEditAddressPropertyForm extends BasicPageForm implements For
} }
public void submitted(FormSectionEvent fse) { public void submitted(FormSectionEvent fse) {
if (m_step != null && if (m_step != null
getSaveCancelSection().getCancelButton().isSelected(fse.getPageState())) { && getSaveCancelSection().getCancelButton().isSelected(fse.getPageState())) {
m_step.cancelStreamlinedCreation(fse.getPageState()); m_step.cancelStreamlinedCreation(fse.getPageState());
} }
} }
@ -171,8 +167,13 @@ public class ContactEditAddressPropertyForm extends BasicPageForm implements For
PageState state = fse.getPageState(); PageState state = fse.getPageState();
Contact contact = (Contact) getItemSelectionModel().getSelectedObject(state); Contact contact = (Contact) getItemSelectionModel().getSelectedObject(state);
if (contact.getAddress() != null && if (getSaveCancelSection().getSaveButton().isSelected(fse.getPageState())) {
getSaveCancelSection().getSaveButton().isSelected(fse.getPageState())) { if (contact.getAddress() == null) {
contact.setAddress(new Address());
contact.getAddress().setName("Address for " + contact.getName() + "(" + contact.getID() + ")");
contact.getAddress().setTitle("Address for " + contact.getName() + "(" + contact.getID() + ")");
}
contact.getAddress().setAddress((String) data.get(ADDRESS)); contact.getAddress().setAddress((String) data.get(ADDRESS));
contact.getAddress().setPostalCode((String) data.get(POSTAL_CODE)); contact.getAddress().setPostalCode((String) data.get(POSTAL_CODE));
contact.getAddress().setCity((String) data.get(CITY)); contact.getAddress().setCity((String) data.get(CITY));

View File

@ -6,7 +6,6 @@
* To change this template, choose Tools | Template Manager * To change this template, choose Tools | Template Manager
* and open the template in the editor. * and open the template in the editor.
*/ */
package com.arsdigita.cms.basetypes.ui; package com.arsdigita.cms.basetypes.ui;
import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormData;
@ -36,14 +35,11 @@ import org.apache.log4j.Logger;
public class ContactEditPersonPropertyForm extends BasicPageForm implements FormProcessListener, FormInitListener, FormSubmissionListener { public class ContactEditPersonPropertyForm extends BasicPageForm implements FormProcessListener, FormInitListener, FormSubmissionListener {
private static final Logger logger = Logger.getLogger(ContactPropertyForm.class); private static final Logger logger = Logger.getLogger(ContactPropertyForm.class);
private ContactPersonPropertiesStep m_step; private ContactPersonPropertiesStep m_step;
public static final String SURNAME = Person.SURNAME; public static final String SURNAME = Person.SURNAME;
public static final String GIVENNAME = Person.GIVENNAME; public static final String GIVENNAME = Person.GIVENNAME;
public static final String TITLEPRE = Person.TITLEPRE; public static final String TITLEPRE = Person.TITLEPRE;
public static final String TITLEPOST = Person.TITLEPOST; public static final String TITLEPOST = Person.TITLEPOST;
/** /**
* ID of the form * ID of the form
*/ */
@ -113,8 +109,8 @@ public class ContactEditPersonPropertyForm extends BasicPageForm implements Form
} }
public void submitted(FormSectionEvent fse) { public void submitted(FormSectionEvent fse) {
if (m_step != null && if (m_step != null
getSaveCancelSection().getCancelButton().isSelected(fse.getPageState())) { && getSaveCancelSection().getCancelButton().isSelected(fse.getPageState())) {
m_step.cancelStreamlinedCreation(fse.getPageState()); m_step.cancelStreamlinedCreation(fse.getPageState());
} }
} }
@ -124,8 +120,14 @@ public class ContactEditPersonPropertyForm extends BasicPageForm implements Form
PageState state = fse.getPageState(); PageState state = fse.getPageState();
Contact contact = (Contact) getItemSelectionModel().getSelectedObject(state); Contact contact = (Contact) getItemSelectionModel().getSelectedObject(state);
if (contact.getPerson() != null && if (getSaveCancelSection().getSaveButton().isSelected(fse.getPageState())) {
getSaveCancelSection().getSaveButton().isSelected(fse.getPageState())) {
if (contact.getPerson() == null) {
contact.setPerson(new Person());
contact.getPerson().setName("Person for " + contact.getName() + "(" + contact.getID() + ")");
contact.getPerson().setTitle("Person for " + contact.getName() + "(" + contact.getID() + ")");
}
contact.getPerson().setSurname((String) data.get(SURNAME)); contact.getPerson().setSurname((String) data.get(SURNAME));
contact.getPerson().setGivenName((String) data.get(GIVENNAME)); contact.getPerson().setGivenName((String) data.get(GIVENNAME));
contact.getPerson().setTitlePre((String) data.get(TITLEPRE)); contact.getPerson().setTitlePre((String) data.get(TITLEPRE));

View File

@ -101,8 +101,8 @@ public class ContactPropertiesStep extends SimpleEditStep {
/* The DisplayComponent for the Basic Properties */ /* The DisplayComponent for the Basic Properties */
DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel); DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel);
sheet.add(GlobalizationUtil.globalize("cms.basetypes.ui.name"), "name"); sheet.add(GlobalizationUtil.globalize("cms.contenttypes.ui.name"), "name");
sheet.add(GlobalizationUtil.globalize("cms.basetypes.ui.title"), "title"); sheet.add(GlobalizationUtil.globalize("cms.contenttypes.ui.title"), "title");
if (!ContentSection.getConfig().getHideLaunchDate()) { if (!ContentSection.getConfig().getHideLaunchDate()) {
sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"), ContentPage.LAUNCH_DATE, new DomainObjectPropertySheet.AttributeFormatter() { sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"), ContentPage.LAUNCH_DATE, new DomainObjectPropertySheet.AttributeFormatter() {

View File

@ -20,6 +20,7 @@ package com.arsdigita.cms.contenttypes;
import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.ContentTypeCollection;
import com.arsdigita.cms.ContentTypeLifecycleDefinition; import com.arsdigita.cms.ContentTypeLifecycleDefinition;
import com.arsdigita.cms.ContentTypeWorkflowTemplate; import com.arsdigita.cms.ContentTypeWorkflowTemplate;
import com.arsdigita.cms.Template; import com.arsdigita.cms.Template;
@ -44,10 +45,12 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.StringTokenizer;
/** /**
* This is the base loader that can be used by individual content types. * This is the base loader that can be used by individual content types.
@ -57,11 +60,11 @@ import java.util.List;
* @author Rafael H. Schloming &lt;rhs@mit.edu&gt; * @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
* @version $Revision: #754 $ $Date: 2005/09/02 $ $Author: sskracic $ * @version $Revision: #754 $ $Date: 2005/09/02 $ $Author: sskracic $
**/ **/
public abstract class AbstractContentTypeLoader extends PackageLoader { public abstract class AbstractContentTypeLoader extends PackageLoader {
public void run(final ScriptContext ctx) { public void run(final ScriptContext ctx) {
new KernelExcursion() { new KernelExcursion() {
protected void excurse() { protected void excurse() {
setEffectiveParty(Kernel.getSystemParty()); setEffectiveParty(Kernel.getSystemParty());
createTypes(ctx); createTypes(ctx);
@ -81,9 +84,10 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
DataCollection sections = ssn.retrieve(ContentSection.BASE_DATA_OBJECT_TYPE); DataCollection sections = ssn.retrieve(ContentSection.BASE_DATA_OBJECT_TYPE);
while (sections.next()) { while (sections.next()) {
ContentSection section = (ContentSection) ContentSection section = (ContentSection) DomainObjectFactory.newInstance(sections.getDataObject());
DomainObjectFactory.newInstance(sections.getDataObject()); if (!isLoadableInto(section)) {
if ( !isLoadableInto(section) ) { continue; } continue;
}
LifecycleDefinitionCollection ldc = LifecycleDefinitionCollection ldc =
section.getLifecycleDefinitions(); section.getLifecycleDefinitions();
@ -103,6 +107,9 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
for (Iterator it = types.iterator(); it.hasNext();) { for (Iterator it = types.iterator(); it.hasNext();) {
final ContentType type = (ContentType) it.next(); final ContentType type = (ContentType) it.next();
// Save the ancestors for this content type
createPedigree(type);
section.addContentType(type); section.addContentType(type);
prepareSection(section, type, ld, wf); prepareSection(section, type, ld, wf);
@ -114,17 +121,17 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
final ContentType type, final ContentType type,
final LifecycleDefinition ld, final LifecycleDefinition ld,
final WorkflowTemplate wf) { final WorkflowTemplate wf) {
ContentTypeLifecycleDefinition.updateLifecycleDefinition ContentTypeLifecycleDefinition.updateLifecycleDefinition(section, type, ld);
(section, type, ld);
ContentTypeWorkflowTemplate.updateWorkflowTemplate ContentTypeWorkflowTemplate.updateWorkflowTemplate(section, type, wf);
(section, type, wf);
} }
protected abstract String[] getTypes(); protected abstract String[] getTypes();
private boolean isLoadableInto(ContentSection section) { private boolean isLoadableInto(ContentSection section) {
if ( section == null ) { throw new NullPointerException("section"); } if (section == null) {
throw new NullPointerException("section");
}
if (getContentSections().size() > 0) { if (getContentSections().size() > 0) {
return getContentSections().contains(section.getName()); return getContentSections().contains(section.getName());
@ -150,7 +157,6 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
return java.util.Collections.EMPTY_LIST; return java.util.Collections.EMPTY_LIST;
} }
/** /**
* This provides an easy way to subtypes to register default * This provides an easy way to subtypes to register default
* templates during the loading. When this is used, it should * templates during the loading. When this is used, it should
@ -171,8 +177,7 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
Assert.isTrue(templateIs != null, "Template not found"); Assert.isTrue(templateIs != null, "Template not found");
final BufferedReader input = new BufferedReader final BufferedReader input = new BufferedReader(new InputStreamReader(templateIs));
(new InputStreamReader(templateIs));
final StringBuffer body = new StringBuffer(); final StringBuffer body = new StringBuffer();
@ -184,16 +189,84 @@ public abstract class AbstractContentTypeLoader extends PackageLoader {
body.append("\n"); body.append("\n");
} }
} catch (IOException ioe) { } catch (IOException ioe) {
throw new UncheckedWrapperException throw new UncheckedWrapperException("Template cannot be read", ioe);
("Template cannot be read", ioe);
} }
template.setText(body.toString()); template.setText(body.toString());
TemplateManagerFactory.getInstance().addTemplate TemplateManagerFactory.getInstance().addTemplate(section, type, template, TemplateManager.PUBLIC_CONTEXT);
(section, type, template, TemplateManager.PUBLIC_CONTEXT);
template.publish(ld, new Date()); template.publish(ld, new Date());
return template; return template;
} }
/**
* Generates the pedigree for this content type
* @param type The new content type
*/
private void createPedigree(ContentType type) {
// The parent content type
ContentType parent = null;
// Get all content types
ContentTypeCollection cts = ContentType.getAllContentTypes();
// This is a brute force method, but I can't come up with something
// better atm without changing either all Loader or the xml-files.
while (cts.next()) {
ContentType ct = cts.getContentType();
try {
Class.forName(type.getClassName()).asSubclass(Class.forName(ct.getClassName()));
} catch (Exception ex) {
// This cast is not valid so type is not a sublacss of ct
continue;
}
// Save the current ct as possible parent if we haven't found any parent yet
// or if the current ancestor list is longer than that one from the possible
// parent earlier found
if (parent == null
|| (parent.getAncestors() != null
&& ct.getAncestors() != null
&& parent.getAncestors().length() < ct.getAncestors().length())) {
parent = ct;
}
}
// If there is a valid parent content type create the pedigree
if (parent != null && !parent.getClassName().equals(type.getClassName())) {
if (parent.getAncestors() != null) {
String parentAncestors = parent.getAncestors();
StringTokenizer strTok = new StringTokenizer(parentAncestors, "/");
// Add parent ancestors to this content types ancestor list
// Also while we iterate through the list, we also need to add
// this content type as sibling to all entries in the ancestor list
while (strTok.hasMoreElements()) {
BigDecimal ctID = (BigDecimal) strTok.nextElement();
// Get the current content type
try {
ContentType ct = new ContentType(ctID);
ct.addSiblings(ctID);
} catch (Exception ex) {
// The db is broken. There is no content type for this ID
}
// Add parent ancestor
type.addAncestor(ctID);
}
}
// Add parent to ancestor list
type.addAncestor(parent.getID());
// Add this to parent siblings
parent.addSiblings(type.getID());
}
}
} }

View File

@ -11,6 +11,10 @@ init com.arsdigita.cms.installer.Initializer {
init com.arsdigita.cms.installer.xml.ContentTypeInitializer { init com.arsdigita.cms.installer.xml.ContentTypeInitializer {
contentTypes = { contentTypes = {
"/WEB-INF/basetypes/Address.xml",
"/WEB-INF/basetypes/Article.xml",
"/WEB-INF/basetypes/Contact.xml",
"/WEB-INF/basetypes/Person.xml",
"/WEB-INF/content-types/Template.xml" "/WEB-INF/content-types/Template.xml"
}; };
} }

View File

@ -18,7 +18,6 @@
*/ */
package com.arsdigita.cms.ui; package com.arsdigita.cms.ui;
import com.arsdigita.bebop.Bebop; import com.arsdigita.bebop.Bebop;
import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Label;
@ -52,10 +51,14 @@ import com.arsdigita.cms.dispatcher.Utilities;
import com.arsdigita.cms.ui.folder.FolderManipulator; import com.arsdigita.cms.ui.folder.FolderManipulator;
import com.arsdigita.cms.ui.folder.FolderSelectionModel; import com.arsdigita.cms.ui.folder.FolderSelectionModel;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.persistence.CompoundFilter;
import com.arsdigita.persistence.FilterFactory;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Iterator;
import java.util.StringTokenizer;
/** /**
* Browse folders and items. If the user clicks on a folder, the folder * Browse folders and items. If the user clicks on a folder, the folder
@ -69,24 +72,16 @@ public class ItemSearchFolderBrowser extends Table {
private static final org.apache.log4j.Logger s_log = private static final org.apache.log4j.Logger s_log =
org.apache.log4j.Logger.getLogger(ItemSearchFolderBrowser.class); org.apache.log4j.Logger.getLogger(ItemSearchFolderBrowser.class);
public static final int MAX_ROWS = 15; public static final int MAX_ROWS = 15;
private static GlobalizedMessage[] s_headers = { private static GlobalizedMessage[] s_headers = {
globalize("cms.ui.folder.name"), globalize("cms.ui.folder.name"),
globalize("cms.ui.folder.title"), globalize("cms.ui.folder.title"),
globalize("cms.ui.folder.type")}; globalize("cms.ui.folder.type")};
private FolderSelectionModel m_currentFolder; private FolderSelectionModel m_currentFolder;
private TableActionListener m_folderChanger; private TableActionListener m_folderChanger;
private TableActionListener m_deleter; private TableActionListener m_deleter;
private TableActionListener m_indexChanger; private TableActionListener m_indexChanger;
private TableColumn m_nameColumn; private TableColumn m_nameColumn;
private Paginator m_paginator; private Paginator m_paginator;
public ItemSearchFolderBrowser(FolderSelectionModel currentFolder) { public ItemSearchFolderBrowser(FolderSelectionModel currentFolder) {
@ -118,11 +113,13 @@ public class ItemSearchFolderBrowser extends Table {
return m_paginator; return m_paginator;
} }
@Override
public void register(Page p) { public void register(Page p) {
super.register(p); super.register(p);
p.addComponentStateParam(this, m_currentFolder.getStateParameter()); p.addComponentStateParam(this, m_currentFolder.getStateParameter());
p.addActionListener(new ActionListener() { p.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
// MP: This action listener should only be called when the // MP: This action listener should only be called when the
// folder browser is visible. // folder browser is visible.
@ -141,7 +138,6 @@ public class ItemSearchFolderBrowser extends Table {
Assert.exists(folder); Assert.exists(folder);
} }
public FolderSelectionModel getFolderSelectionModel() { public FolderSelectionModel getFolderSelectionModel() {
return m_currentFolder; return m_currentFolder;
} }
@ -150,15 +146,20 @@ public class ItemSearchFolderBrowser extends Table {
extends AbstractTableModelBuilder implements PaginationModelBuilder { extends AbstractTableModelBuilder implements PaginationModelBuilder {
private RequestLocal m_size = new RequestLocal() { private RequestLocal m_size = new RequestLocal() {
@Override
protected Object initialValue(PageState state) { protected Object initialValue(PageState state) {
Folder.ItemCollection itemColl = getItemCollection(state); Folder.ItemCollection itemColl = getItemCollection(state);
if( null == itemColl ) return new Integer( 0 ); if (null == itemColl) {
return new Integer(0);
}
return new Integer((int) itemColl.size()); return new Integer((int) itemColl.size());
} }
}; };
private RequestLocal m_itemColl = new RequestLocal() { private RequestLocal m_itemColl = new RequestLocal() {
@Override
protected Object initialValue(PageState state) { protected Object initialValue(PageState state) {
Folder.ItemCollection itemColl = getItemCollection(state); Folder.ItemCollection itemColl = getItemCollection(state);
@ -175,11 +176,11 @@ public class ItemSearchFolderBrowser extends Table {
Folder f = getCurrentFolder(s); Folder f = getCurrentFolder(s);
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
if( null == f ) if (null == f) {
s_log.debug("Selected folder is null"); s_log.debug("Selected folder is null");
else } else {
s_log.debug( "Selected folder: " + f.getLabel() + " " + s_log.debug("Selected folder: " + f.getLabel() + " " + f.getOID().toString());
f.getOID().toString() ); }
} }
if (f == null) { if (f == null) {
@ -194,19 +195,42 @@ public class ItemSearchFolderBrowser extends Table {
Folder f = getCurrentFolder(state); Folder f = getCurrentFolder(state);
Folder.ItemCollection itemColl = f.getPrimaryInstances(); Folder.ItemCollection itemColl = f.getPrimaryInstances();
if( null == itemColl ) return null; if (null == itemColl) {
return null;
}
BigDecimal singleTypeID = BigDecimal singleTypeID =
(BigDecimal) state.getValue (new BigDecimalParameter (BigDecimal) state.getValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM));
(ItemSearch.SINGLE_TYPE_PARAM));
if (singleTypeID != null) if (singleTypeID != null) {
itemColl.addEqualsFilter (ContentItem.CONTENT_TYPE +
"." + ContentType.ID, singleTypeID); // The Filter Factory
FilterFactory ff = itemColl.getFilterFactory();
// Create an or-filter
CompoundFilter or = ff.or();
// The content type must be either of the requested type
or.addFilter(ff.equals(ContentItem.CONTENT_TYPE + "." + ContentType.ID, singleTypeID));
// Or must be a sibling of the requested type
try {
ContentType ct = new ContentType(singleTypeID);
StringTokenizer strTok = new StringTokenizer(ct.getSiblings(), "/");
while (strTok.hasMoreElements()) {
or.addFilter(ff.equals(ContentItem.CONTENT_TYPE + "." + ContentType.ID, (String) strTok.nextElement()));
}
} catch (Exception ex) {
// WTF? The selected content type does not exist in the table???
}
itemColl.addFilter(or);
}
itemColl.addOrder("isFolder desc"); itemColl.addOrder("isFolder desc");
itemColl.addOrder("lower(item." + itemColl.addOrder("lower(item."
ContentItem.NAME + ") "); + ContentItem.NAME + ") ");
return itemColl; return itemColl;
} }
@ -227,8 +251,8 @@ public class ItemSearchFolderBrowser extends Table {
public boolean isVisible(PageState state) { public boolean isVisible(PageState state) {
int size = ((Integer) m_size.get(state)).intValue(); int size = ((Integer) m_size.get(state)).intValue();
return ItemSearchFolderBrowser.this.isVisible(state) && return ItemSearchFolderBrowser.this.isVisible(state)
( size > MAX_ROWS ); && (size > MAX_ROWS);
} }
} }
@ -236,31 +260,27 @@ public class ItemSearchFolderBrowser extends Table {
* Produce links to view an item or control links for folders * Produce links to view an item or control links for folders
* to change into the folder. * to change into the folder.
*/ */
private class NameCellRenderer extends DefaultTableCellRenderer private class NameCellRenderer extends DefaultTableCellRenderer {
{
public NameCellRenderer() public NameCellRenderer() {
{
super(true); super(true);
} }
@Override
public Component getComponent(Table table, PageState state, public Component getComponent(Table table, PageState state,
Object value, boolean isSelected, Object value, boolean isSelected,
Object key, int row, int column) Object key, int row, int column) {
{
Folder.ItemCollection coll = (Folder.ItemCollection) value; Folder.ItemCollection coll = (Folder.ItemCollection) value;
String name = coll.getName(); String name = coll.getName();
if ( coll.isFolder() ) if (coll.isFolder()) {
return super.getComponent(table, state, name, return super.getComponent(table, state, name, isSelected, key, row, column);
isSelected, key, row, column); } else {
else
{
ContentSection section = CMS.getContext().getContentSection(); ContentSection section = CMS.getContext().getContentSection();
BigDecimal id = (BigDecimal) key; BigDecimal id = (BigDecimal) key;
if (section == null) if (section == null) {
return new Label(name); return new Label(name);
else } else {
{
//ItemResolver resolver = section.getItemResolver(); //ItemResolver resolver = section.getItemResolver();
//String url = //String url =
@ -270,16 +290,14 @@ public class ItemSearchFolderBrowser extends Table {
SimpleContainer container = new SimpleContainer(); SimpleContainer container = new SimpleContainer();
String widget = String widget =
(String) state.getValue (new StringParameter (String) state.getValue(new StringParameter(ItemSearchPopup.WIDGET_PARAM));
(ItemSearchPopup.WIDGET_PARAM)); boolean useURL = "true".equals(state.getValue(new StringParameter(ItemSearchPopup.URL_PARAM)));
boolean useURL = "true".equals
(state.getValue(new StringParameter(ItemSearchPopup.URL_PARAM)));
String fillString = useURL ? String fillString = useURL
ItemSearchPopup.getItemURL(state.getRequest(), ? ItemSearchPopup.getItemURL(state.getRequest(),
coll.getDomainObject().getOID()) : coll.getDomainObject().getOID())
id + : id
" (" + name + ")"; + " (" + name + ")";
Label js = new Label(generateJSLabel(id, widget, Label js = new Label(generateJSLabel(id, widget,
fillString), fillString),
@ -299,26 +317,25 @@ public class ItemSearchFolderBrowser extends Table {
} }
} }
private String generateJSLabel(BigDecimal id, String widget, String fill) private String generateJSLabel(BigDecimal id, String widget, String fill) {
{
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append(" <script language=javascript> " + buffer.append(" <script language=javascript> "
" <!-- \n" + + " <!-- \n"
" function fillItem" + + " function fillItem"
id + + id
"() { \n" + + "() { \n"
" window.opener.document." + + " window.opener.document."
widget + ".value=\"" + fill + "\";\n"); + widget + ".value=\"" + fill + "\";\n");
// set protocol to 'other' in FCKEditor, else relative url prepended by http:// // set protocol to 'other' in FCKEditor, else relative url prepended by http://
if (Bebop.getConfig().getDHTMLEditor().equals(BebopConstants.BEBOP_FCKEDITOR)) { if (Bebop.getConfig().getDHTMLEditor().equals(BebopConstants.BEBOP_FCKEDITOR)) {
buffer.append("window.opener.document.getElementById('cmbLinkProtocol').value=\"\";\n"); buffer.append("window.opener.document.getElementById('cmbLinkProtocol').value=\"\";\n");
} }
buffer.append( " self.close(); \n" + buffer.append(" self.close(); \n"
" return false; \n" + + " return false; \n"
" } \n" + + " } \n"
" --> \n" + + " --> \n"
" </script> "); + " </script> ");
return buffer.toString(); return buffer.toString();
} }
@ -327,33 +344,27 @@ public class ItemSearchFolderBrowser extends Table {
/** /**
* Table model around ItemCollection * Table model around ItemCollection
*/ */
private static class FolderTableModel implements TableModel private static class FolderTableModel implements TableModel {
{
private static final int NAME = 0; private static final int NAME = 0;
private static final int TITLE = 1; private static final int TITLE = 1;
private static final int TYPE = 2; private static final int TYPE = 2;
private Folder.ItemCollection m_itemColl; private Folder.ItemCollection m_itemColl;
public FolderTableModel(Folder.ItemCollection itemColl) public FolderTableModel(Folder.ItemCollection itemColl) {
{
m_itemColl = itemColl; m_itemColl = itemColl;
} }
public int getColumnCount() public int getColumnCount() {
{
return 3; return 3;
} }
public boolean nextRow() public boolean nextRow() {
{
return m_itemColl != null ? m_itemColl.next() : false; return m_itemColl != null ? m_itemColl.next() : false;
} }
public Object getElementAt(int columnIndex) public Object getElementAt(int columnIndex) {
{ switch (columnIndex) {
switch (columnIndex)
{
case NAME: case NAME:
return m_itemColl; return m_itemColl;
case TITLE: case TITLE:
@ -361,14 +372,12 @@ public class ItemSearchFolderBrowser extends Table {
case TYPE: case TYPE:
return m_itemColl.getTypeLabel(); return m_itemColl.getTypeLabel();
default: default:
throw new throw new IndexOutOfBoundsException("Column index " + columnIndex
IndexOutOfBoundsException ("Column index " + columnIndex + + " not in table model.");
" not in table model.");
} }
} }
public Object getKeyAt(int columnIndex) public Object getKeyAt(int columnIndex) {
{
// Mark folders by using their negative ID (dirty, dirty) // Mark folders by using their negative ID (dirty, dirty)
return (m_itemColl.isFolder()) ? m_itemColl.getID().negate() return (m_itemColl.isFolder()) ? m_itemColl.getID().negate()
: m_itemColl.getID(); : m_itemColl.getID();
@ -376,6 +385,7 @@ public class ItemSearchFolderBrowser extends Table {
} }
private class FolderChanger extends TableActionAdapter { private class FolderChanger extends TableActionAdapter {
public void cellSelected(TableActionEvent e) { public void cellSelected(TableActionEvent e) {
PageState s = e.getPageState(); PageState s = e.getPageState();
int col = e.getColumn().intValue(); int col = e.getColumn().intValue();
@ -401,5 +411,4 @@ public class ItemSearchFolderBrowser extends Table {
private static GlobalizedMessage globalize(String key) { private static GlobalizedMessage globalize(String key) {
return FolderManipulator.globalize(key); return FolderManipulator.globalize(key);
} }
} }

View File

@ -78,6 +78,7 @@ public class ItemSearchParameter extends StringParameter {
* @throws IllegalArgumentException if the request parameter does not * @throws IllegalArgumentException if the request parameter does not
* look like a valid email address. * look like a valid email address.
*/ */
@Override
public Object transformValue(HttpServletRequest request) public Object transformValue(HttpServletRequest request)
throws IllegalArgumentException { throws IllegalArgumentException {
@ -86,6 +87,7 @@ public class ItemSearchParameter extends StringParameter {
return unmarshal(itemStr); return unmarshal(itemStr);
} }
@Override
public Object unmarshal(String encoded) public Object unmarshal(String encoded)
throws IllegalArgumentException { throws IllegalArgumentException {
@ -113,16 +115,13 @@ public class ItemSearchParameter extends StringParameter {
} }
if (m_contentType != null && if (m_contentType != null &&
!contentItem.getContentType().equals(m_contentType)) { !contentItem.isContentType(m_contentType)) {
return null; return null;
/*
throw new IllegalArgumentException
(encoded + " is not a valid " + m_contentType.getLabel());
*/
} }
return contentItem; return contentItem;
} }
@Override
public String marshal(Object value) { public String marshal(Object value) {
if (value == null) { if (value == null) {
return null; return null;
@ -132,6 +131,7 @@ public class ItemSearchParameter extends StringParameter {
} }
} }
@Override
public Class getValueClass() { public Class getValueClass() {
return ContentPage.class; return ContentPage.class;
} }

View File

@ -44,7 +44,6 @@ import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.URL; import com.arsdigita.web.URL;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* A class representing a content item search field in an HTML form. * A class representing a content item search field in an HTML form.
* *
@ -63,12 +62,10 @@ public class ItemSearchWidget extends FormSection
private Label m_bottomHR; private Label m_bottomHR;
private ContentType m_contentType; private ContentType m_contentType;
private ItemSearchSectionInline m_searchComponent; private ItemSearchSectionInline m_searchComponent;
private String m_name; private String m_name;
private String m_searchName; private String m_searchName;
private String m_clearName; private String m_clearName;
private ParameterModel m_model; private ParameterModel m_model;
public static final String BEBOP_ITEM_SEARCH = "bebop:itemSearch"; public static final String BEBOP_ITEM_SEARCH = "bebop:itemSearch";
private class ItemFragment extends TextField { private class ItemFragment extends TextField {
@ -82,6 +79,7 @@ public class ItemSearchWidget extends FormSection
this.setSize(35); this.setSize(35);
} }
} }
private class SearchFragment extends Submit { private class SearchFragment extends Submit {
private ItemSearchWidget parent; private ItemSearchWidget parent;
@ -98,11 +96,10 @@ public class ItemSearchWidget extends FormSection
} }
public boolean isVisible(PageState ps) { public boolean isVisible(PageState ps) {
return (!(parent.m_search.isSelected(ps) || return (!(parent.m_search.isSelected(ps)
parent.m_searchComponent.hasQuery(ps)) && || parent.m_searchComponent.hasQuery(ps))
super.isVisible(ps)); && super.isVisible(ps));
} }
} }
private class ClearFragment extends Submit { private class ClearFragment extends Submit {
@ -125,7 +122,6 @@ public class ItemSearchWidget extends FormSection
super(name, escaping); super(name, escaping);
this.parent = parent; this.parent = parent;
} }
} }
private class ItemSearchFragment extends ItemSearchSectionInline { private class ItemSearchFragment extends ItemSearchSectionInline {
@ -139,11 +135,10 @@ public class ItemSearchWidget extends FormSection
@Override @Override
public boolean isVisible(PageState ps) { public boolean isVisible(PageState ps) {
return ((m_search.isSelected(ps) || return ((m_search.isSelected(ps)
hasQuery(ps)) && || hasQuery(ps))
super.isVisible(ps)); && super.isVisible(ps));
} }
} }
private class HRLabel extends Label { private class HRLabel extends Label {
@ -154,12 +149,12 @@ public class ItemSearchWidget extends FormSection
@Override @Override
public boolean isVisible(PageState ps) { public boolean isVisible(PageState ps) {
return ((m_search.isSelected(ps) || return ((m_search.isSelected(ps)
m_searchComponent.hasQuery(ps)) && || m_searchComponent.hasQuery(ps))
super.isVisible(ps)); && super.isVisible(ps));
}
} }
}
/** /**
* Construct a new ItemSearchWidget. The model must be an ItemSearchParameter * Construct a new ItemSearchWidget. The model must be an ItemSearchParameter
*/ */
@ -176,8 +171,8 @@ public class ItemSearchWidget extends FormSection
if (!(model instanceof ItemSearchParameter)) { if (!(model instanceof ItemSearchParameter)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The ItemSearch widget " + model.getName() + "The ItemSearch widget " + model.getName()
" must be backed by a ItemSearchParameter parmeter model"); + " must be backed by a ItemSearchParameter parmeter model");
} }
m_name = model.getName(); m_name = model.getName();
@ -198,6 +193,7 @@ public class ItemSearchWidget extends FormSection
m_clear = new ClearFragment(m_clearName, this); m_clear = new ClearFragment(m_clearName, this);
m_jsLabel = new LabelFragment("", false, this); m_jsLabel = new LabelFragment("", false, this);
m_jsLabel.addPrintListener(new PrintListener() { m_jsLabel.addPrintListener(new PrintListener() {
public void prepare(PrintEvent event) { public void prepare(PrintEvent event) {
PageState state = event.getPageState(); PageState state = event.getPageState();
Label t = (Label) event.getTarget(); Label t = (Label) event.getTarget();
@ -222,16 +218,16 @@ public class ItemSearchWidget extends FormSection
URL url = URL.there(state.getRequest(), searchURL, params); URL url = URL.there(state.getRequest(), searchURL, params);
t.setLabel(" <script language=javascript> " + t.setLabel(" <script language=javascript> "
" <!-- \n" + + " <!-- \n"
" function " + + " function "
m_item.getName().replace('.','_') + + m_item.getName().replace('.', '_')
"Popup(theForm) { \n" + + "Popup(theForm) { \n"
" aWindow = window.open(\"" + url + + " aWindow = window.open(\"" + url
"\", \"search\", \"toolbar=no,width=800,height=600,status=no,scrollbars=yes,resize=yes,menubar=no\");\n return false;\n" + + "\", \"search\", \"toolbar=no,width=800,height=600,status=no,scrollbars=yes,resize=yes,menubar=no\");\n return false;\n"
" } \n" + + " } \n"
" --> \n" + + " --> \n"
" </script> "); + " </script> ");
} }
}); });
m_topHR = new HRLabel(); m_topHR = new HRLabel();
@ -251,6 +247,7 @@ public class ItemSearchWidget extends FormSection
} }
@Override
public void register(Page p) { public void register(Page p) {
super.register(p); super.register(p);
p.setVisibleDefault(m_topHR, false); p.setVisibleDefault(m_topHR, false);
@ -261,13 +258,15 @@ public class ItemSearchWidget extends FormSection
public ItemSearchWidget(String name) { public ItemSearchWidget(String name) {
this(new ItemSearchParameter(name)); this(new ItemSearchParameter(name));
} }
public ItemSearchWidget(String name, public ItemSearchWidget(String name,
String objectType) String objectType)
throws DataObjectNotFoundException { throws DataObjectNotFoundException {
this(name, (objectType == null || objectType.length()==0 ? this(name, (objectType == null || objectType.length() == 0
null : ? null
ContentType.findByAssociatedObjectType(objectType))); : ContentType.findByAssociatedObjectType(objectType)));
} }
public ItemSearchWidget(String name, public ItemSearchWidget(String name,
ContentType contentType) { ContentType contentType) {
this(new ItemSearchParameter(name, contentType), contentType); this(new ItemSearchParameter(name, contentType), contentType);
@ -276,9 +275,11 @@ public class ItemSearchWidget extends FormSection
public Submit getSearchButton() { public Submit getSearchButton() {
return m_search; return m_search;
} }
public Submit getClearButton() { public Submit getClearButton() {
return m_clear; return m_clear;
} }
public TextField getItemField() { public TextField getItemField() {
return m_item; return m_item;
} }
@ -376,5 +377,4 @@ public class ItemSearchWidget extends FormSection
} }
} }
} }
} }