From 86beaa1ec7da7782010ccf9e3534c67f99f97f4b Mon Sep 17 00:00:00 2001 From: quasi Date: Thu, 7 Nov 2013 12:04:11 +0000 Subject: [PATCH] =?UTF-8?q?*=20Meine=20Author=20Angaben=20korrigiert=20*?= =?UTF-8?q?=20Sortierung=20der=20angeh=C3=A4ngten=20Bilder=20ist=20nun=20m?= =?UTF-8?q?=C3=B6glich=20*=20Cursor=20kann=20sich=20nun=20auch=20r=C3=BCck?= =?UTF-8?q?w=C3=A4rts=20bewegen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wahrscheinlich noch mehr, daß mir gerade nicht einfällt git-svn-id: https://svn.libreccm.org/ccm/trunk@2418 8810af33-2d31-482b-a856-94f89814c4df --- .../ImageStepResources.properties | 2 + .../ImageStepResources_de.properties | 2 + .../ImageStepResources_en.properties | 2 + .../contentassets/ItemImageAttachment.java | 75 +- .../ItemImageAttachmentInitializer.java | 8 + .../ui/ImageComponentAttachListener.java | 2 +- .../cms/contentassets/ui/ImageStep.java | 257 +- .../contentassets/ui/ImageStepDisplay.java | 549 ++-- .../cms/contentassets/ui/ImageStepEdit.java | 2 +- .../com/arsdigita/cms/CMSResources.properties | 1 + .../arsdigita/cms/CMSResources_de.properties | 3 +- .../cms/CMSResources_en_GB.properties | 1 + .../arsdigita/cms/CMSResources_fr.properties | 1 + .../src/com/arsdigita/cms/CachedImage.java | 2 +- .../src/com/arsdigita/cms/ContentSection.java | 2 +- .../arsdigita/cms/ContentSectionServlet.java | 2 +- ccm-cms/src/com/arsdigita/cms/ImageAsset.java | 2 +- .../cms/LanguageInvariantContentItem.java | 2 +- .../src/com/arsdigita/cms/LoaderConfig.java | 2 +- .../contentsection/ContentSectionConfig.java | 2 +- .../contentsection/ContentSectionSetup.java | 2 +- .../AbstractContentTypeLoader.java | 2 +- .../cms/contenttypes/GenericAddress.java | 2 +- .../contenttypes/GenericContactConfig.java | 2 +- .../contenttypes/GenericContactEntryKeys.java | 2 +- .../cms/contenttypes/GenericPerson.java | 2 +- .../com/arsdigita/cms/contenttypes/Link.java | 2 +- .../contenttypes/LinkTraversalAdapter.java | 2 +- .../ui/GenericAddressPropertyForm.java | 2 +- .../ui/GenericContactEntriesTable.java | 2 +- .../ui/GenericContactEntryAddForm.java | 2 +- .../ui/GenericContactPropertiesStep.java | 2 +- .../ui/GenericContactTypeAddForm.java | 2 +- .../ui/GenericContactTypePropertiesStep.java | 2 +- .../ui/GenericContactTypeTable.java | 2 +- .../ui/GenericPersonContactAddForm.java | 2 +- .../GenericPersonContactPropertiesStep.java | 2 +- .../ui/GenericPersonContactTable.java | 2 +- .../contenttypes/ui/GenericPersonCreate.java | 2 +- .../cms/contenttypes/ui/LinkPropertyForm.java | 2 +- .../arsdigita/cms/dispatcher/BaseImage.java | 2 +- .../cms/dispatcher/DownloadImage.java | 2 +- .../arsdigita/cms/dispatcher/StreamImage.java | 2 +- .../arsdigita/cms/ui/CMSItemSearchPage.java | 2 +- .../com/arsdigita/cms/ui/ContentItemPage.java | 4 +- .../ui/DefaultImageBrowserModelBuilder.java | 2 +- .../com/arsdigita/cms/ui/ImageBrowser.java | 2 +- .../com/arsdigita/cms/ui/ImageChooser.java | 2 +- .../com/arsdigita/cms/ui/ImageComponent.java | 2 +- .../ui/ImageComponentAbstractListener.java | 189 +- .../cms/ui/ImageComponentAdminListener.java | 2 +- .../cms/ui/ImageComponentSelectListener.java | 2 +- .../com/arsdigita/cms/ui/ImageDisplay.java | 197 +- .../cms/ui/ImageLibraryComponent.java | 2 +- .../com/arsdigita/cms/ui/ImageSelectPage.java | 250 +- .../cms/ui/ImageSelectResultComponent.java | 146 +- .../cms/ui/ImageUploadComponent.java | 218 +- .../src/com/arsdigita/cms/ui/ImagesPane.java | 2 +- .../cms/ui/ItemSearchCreateItemPane.java | 2 +- .../com/arsdigita/cms/ui/ItemSearchPage.java | 2 +- .../cms/ui/category/CategoryItemPane.java | 2 +- .../category/CategoryLocalizationAddForm.java | 2 +- .../CategoryLocalizationEditForm.java | 2 +- .../ui/category/CategoryLocalizationForm.java | 2 +- .../category/CategoryLocalizationTable.java | 2 +- .../cms/ui/folder/AbstractFolderPicker.java | 2 +- .../cms/ui/folder/FlatFolderPicker.java | 2 +- .../cms/ui/folder/FolderBrowser.java | 4 +- .../arsdigita/cms/ui/role/BaseRoleForm.java | 2 + .../cms/ui/search/ItemQueryComponent.java | 2 +- .../cms/ui/workflow/AssignedTaskSection.java | 2 +- .../com/arsdigita/cms/util/LanguageUtil.java | 2 +- ccm-core/src/com/arsdigita/bebop/Page.java | 2364 +++++++++-------- .../arsdigita/bebop/SaveCancelSection.java | 2 +- .../src/com/arsdigita/bebop/form/Date.java | 2 +- .../com/arsdigita/bebop/form/DateTime.java | 2 +- .../src/com/arsdigita/bebop/form/Time.java | 2 +- .../parameters/IncompleteDateParameter.java | 2 +- .../categorization/CategorizationConfig.java | 2 +- .../categorization/CategoryLocalization.java | 2 +- .../CategoryLocalizationCollection.java | 2 +- .../globalization/GlobalizationHelper.java | 2 +- .../kernel/permissions/PermissionManager.java | 1 + .../arsdigita/persistence/DataQueryImpl.java | 1474 +++++----- .../ui/filters/DateRangeFilterWidget.java | 2 +- .../arsdigita/ui/admin/AdminConstants.java | 6 +- .../ui/admin/AdminResources.properties | 6 +- .../ui/admin/AdminResources_de.properties | 6 +- .../ui/admin/AdminResources_en.properties | 6 +- .../ui/admin/AdminResources_fr.properties | 6 +- .../com/arsdigita/util/SystemInformation.java | 2 +- .../webdevsupport/ui/ConfigParameterList.java | 3 + .../xml/formatters/DateFormatter.java | 2 +- .../xml/formatters/DateTimeFormatter.java | 2 +- .../xml/formatters/TimeFormatter.java | 2 +- .../src/com/redhat/persistence/Cursor.java | 303 ++- 96 files changed, 3271 insertions(+), 2949 deletions(-) diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources.properties b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources.properties index 7c4904b97..1f919eb15 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources.properties +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources.properties @@ -3,3 +3,5 @@ com.arsdigita.cms.contentassets.image_step_description=Add Images cms.contentassets.ui.image_step.add_image=Add Image cms.contentassets.ui.image_step.no_image_attached=This item does not have any associated images. cms.contentassets.ui.image_step.remove_attached_image=Remove image attachment +cms.contentassets.ui.image_step.move_attached_image_down=Move down +cms.contentassets.ui.image_step.move_attached_image_up=Move up diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_de.properties b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_de.properties index a4f9cd37e..6aeae029d 100644 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_de.properties +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_de.properties @@ -3,3 +3,5 @@ com.arsdigita.cms.contentassets.image_step_description=Bild hinzuf\u00fcgen cms.contentassets.ui.image_step.add_image=Bild hinzuf\u00fcgen cms.contentassets.ui.image_step.no_image_attached=Diesem Dokument ist noch kein Bild zugeordnet. cms.contentassets.ui.image_step.remove_attached_image=Aus der Liste entfernen +cms.contentassets.ui.image_step.move_attached_image_down=Nach unten verschieben +cms.contentassets.ui.image_step.move_attached_image_up=Nach oben verschieben diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_en.properties b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_en.properties index 7c4904b97..1f919eb15 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_en.properties +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources_en.properties @@ -3,3 +3,5 @@ com.arsdigita.cms.contentassets.image_step_description=Add Images cms.contentassets.ui.image_step.add_image=Add Image cms.contentassets.ui.image_step.no_image_attached=This item does not have any associated images. cms.contentassets.ui.image_step.remove_attached_image=Remove image attachment +cms.contentassets.ui.image_step.move_attached_image_down=Move down +cms.contentassets.ui.image_step.move_attached_image_up=Move up diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachment.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachment.java index a599c9d21..4f693f5e7 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachment.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachment.java @@ -32,30 +32,38 @@ import com.arsdigita.persistence.OID; import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.metadata.Property; import com.arsdigita.util.Assert; +import java.math.BigDecimal; import org.apache.log4j.Logger; /** * @version $Revision: #3 $ $Date: 2004/04/08 $ * @version $Id: $ - **/ + * + * @author unknown + * @author Sören Bernstein + * + */ public class ItemImageAttachment extends ACSObject implements CustomCopy { - /** PDL property name for contact details */ + /** + * PDL property name for contact details + */ public static final String IMAGE = "image"; public static final String ITEM = "item"; public static final String USE_CONTEXT = "useContext"; public static final String CAPTION = "caption"; public static final String DESCRIPTION = "description"; public static final String TITLE = "title"; + public static final String SORTKEY = "sortKey"; public static final String IMAGE_ATTACHMENTS = "imageAttachments"; public static final String ITEM_ATTACHMENTS = "itemAttachments"; public static final String IMAGE_LINK = "imageLink"; - /** Data object type for this domain object */ + /** + * Data object type for this domain object + */ public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.cms.contentassets.ItemImageAttachment"; private static final Logger s_log = Logger.getLogger(ItemImageAttachment.class); - - private static final ItemImageAttachmentConfig - s_config = ItemImageAttachmentConfig.instanceOf(); + private static final ItemImageAttachmentConfig s_config = ItemImageAttachmentConfig.instanceOf(); private ItemImageAttachment() { this(BASE_DATA_OBJECT_TYPE); @@ -69,6 +77,7 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { super(type); } + @Override public String getBaseDataObjectType() { return BASE_DATA_OBJECT_TYPE; } @@ -80,7 +89,18 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { set(IMAGE, image); } - public static ItemImageAttachment retrieve(OID oid) { + /** + * Before saving this object, make sure SORTKEY is set + */ + @Override + protected void beforeSave() { + if(isNew() || getSortKey() == null || getSortKey() == 0) { + setSortKey(getNextSortKey(getItem())); + } + super.beforeSave(); + } + + public static ItemImageAttachment retrieve(OID oid) { return (ItemImageAttachment) DomainObjectFactory.newInstance(oid); } @@ -116,7 +136,9 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { set(ITEM, item); } - /** Retrieves links for a content item */ + /** + * Retrieves links for a content item + */ public static DataCollection getImageAttachments(ContentItem item) { Assert.exists(item, ContentItem.class); @@ -126,6 +148,8 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { DataCollection attachments = SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE); attachments.addEqualsFilter(ITEM + ".id", item.getID()); + // Order by SORTKEY + attachments.addOrder(SORTKEY); return attachments; } @@ -162,20 +186,34 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { return (String) get(DESCRIPTION); } + public void setSortKey(Integer sortkey) { + set(SORTKEY, new BigDecimal(sortkey)); + } + + public Integer getSortKey() { + BigDecimal sortkey = ((BigDecimal) get(SORTKEY)); + if (sortkey != null) { + return sortkey.intValue(); + } else { + return 0; + } + } + /** * Automatically publish an unpublished image */ + @Override public boolean copyProperty(final CustomCopy source, - final Property property, - final ItemCopier copier) { + final Property property, + final ItemCopier copier) { String attribute = property.getName(); if (ItemCopier.VERSION_COPY == copier.getCopyType() - && IMAGE.equals(attribute)) { + && IMAGE.equals(attribute)) { ItemImageAttachment attachment = (ItemImageAttachment) source; ReusableImageAsset image = attachment.getImage(); ReusableImageAsset liveImage = - (ReusableImageAsset) image.getLiveVersion(); + (ReusableImageAsset) image.getLiveVersion(); if (null == liveImage) { liveImage = (ReusableImageAsset) image.createLiveVersion(); @@ -208,10 +246,21 @@ public class ItemImageAttachment extends ACSObject implements CustomCopy { // when we delete the link, the image still references it in DB // can't make it composite because then image is deleted if we delete // link. Have to set link to null first (I think) - DomainObject link = DomainObjectFactory.newInstance((DataObject)get(IMAGE_LINK)); + DomainObject link = DomainObjectFactory.newInstance((DataObject) get(IMAGE_LINK)); set(IMAGE_LINK, null); save(); link.delete(); } + + /** + * Get the next sort key for the list of {@link ItemImageAttachment}s for an + * item. + * + * @param item The {@link ContentItem} the list of images is looked up for + * @return the next sortkey, basically length of the list + 1 + */ + public static Integer getNextSortKey(ContentItem item) { + return new Integer((int) ItemImageAttachment.getImageAttachments(item).size() + 1); + } } diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentInitializer.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentInitializer.java index 4e70e443d..03d018ebf 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentInitializer.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentInitializer.java @@ -53,6 +53,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { DomainObjectFactory.registerInstantiator( ItemImageAttachment.BASE_DATA_OBJECT_TYPE, new DomainObjectInstantiator() { + @Override protected DomainObject doNewInstance(DataObject obj) { return new ItemImageAttachment(obj); } @@ -70,6 +71,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { * The base type against which the asset is defined, * typically com.arsdigita.cms.ContentPage */ + @Override public String getBaseType() { return ContentPage.BASE_DATA_OBJECT_TYPE; } @@ -78,6 +80,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { * Returns the path to the XML file defintions for the asset, eg: * /WEB-INF/traversal-adapters/com/arsdigita/cms/contentassets/FileAttachments.xml */ + @Override public String getTraversalXML() { return "/WEB-INF/traversal-adapters/com/arsdigita/" + "cms/contentassets/ItemImageAttachment.xml"; @@ -87,6 +90,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { * The name of the association between the item * and the asset, eg 'fileAttachments'. */ + @Override public String getProperty() { return "imageAttachments"; } @@ -94,6 +98,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { /** * The class of the authoring kit step */ + @Override public Class getAuthoringStep() { return ImageStep.class; } @@ -101,6 +106,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { /** * The label for the authoring step */ + @Override public GlobalizedMessage getAuthoringStepLabel() { return new GlobalizedMessage("com.arsdigita.cms.contentassets.image_step_label", "com.arsdigita.cms.contentassets.ImageStepResources"); @@ -109,6 +115,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { /** * The description for the authoring step */ + @Override public GlobalizedMessage getAuthoringStepDescription() { return new GlobalizedMessage("com.arsdigita.cms.contentassets.image_step_description", "com.arsdigita.cms.contentassets.ImageStepResources"); @@ -117,6 +124,7 @@ public class ItemImageAttachmentInitializer extends ContentAssetInitializer { /** * The sort key for the authoring step */ + @Override public int getAuthoringStepSortKey() { return ItemImageAttachmentConfig.instanceOf().getImageStepSortKey(); } diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageComponentAttachListener.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageComponentAttachListener.java index ccf20f4e5..e497642a5 100644 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageComponentAttachListener.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageComponentAttachListener.java @@ -34,7 +34,7 @@ import org.apache.log4j.Logger; * * This listerner is used by {@link ImageStepEdit}. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageComponentAttachListener extends ImageComponentAbstractListener { diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStep.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStep.java index 7294d4c6c..fe0505b91 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStep.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStep.java @@ -39,162 +39,163 @@ import java.util.Iterator; import org.apache.log4j.Logger; /** - * Pluggable authoring step as the main entry point to add an ImageAsset to a + * Pluggable authoring step as the main entry point to add an ImageAsset to a * content item. - * + * * @author unknown - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageStep extends SecurityPropertyEditor { - private static final Logger s_log = Logger.getLogger(ImageStep.class); - private final ItemSelectionModel m_itemSelection; - private final AttachmentSelectionModel m_attachmentSelection; - private final AuthoringKitWizard m_parent; - private final ImageStepDisplay m_display; - private final ImageStepEdit m_add; - private final OIDParameter m_attachmentOID; + private static final Logger s_log = Logger.getLogger(ImageStep.class); + private final ItemSelectionModel m_itemSelection; + private final AttachmentSelectionModel m_attachmentSelection; + private final AuthoringKitWizard m_parent; + private final ImageStepDisplay m_display; + private final ImageStepEdit m_add; + private final OIDParameter m_attachmentOID; - /** - * Constructor. - * - * @param itemModel - * @param parent - */ - public ImageStep(ItemSelectionModel itemModel, - AuthoringKitWizard parent) { - super(); + /** + * Constructor. + * + * @param itemModel The {@link ItemSelectionModel} to use with this + * instance + * @param parent The parent {@link AuthoringKitWizard} + */ + public ImageStep(ItemSelectionModel itemModel, + AuthoringKitWizard parent) { + super(); - m_itemSelection = itemModel; - m_parent = parent; + m_itemSelection = itemModel; + m_parent = parent; - m_attachmentOID = new OIDParameter("attachmentID"); - m_attachmentSelection = new AttachmentSelectionModel(); + m_attachmentOID = new OIDParameter("attachmentID"); + m_attachmentSelection = new AttachmentSelectionModel(); - /* Create ImageEditStep to add images to the current item */ - m_add = new ImageStepEdit(this); - WorkflowLockedComponentAccess addCA = - new WorkflowLockedComponentAccess(m_add, m_itemSelection); - addComponent("add", - ImageStepGlobalizationUtil.globalize( - "cms.contentassets.ui.image_step.add_image"), - addCA); + /* Create ImageEditStep to add images to the current item */ + m_add = new ImageStepEdit(this); + WorkflowLockedComponentAccess addCA = + new WorkflowLockedComponentAccess(m_add, m_itemSelection); + addComponent("add", + ImageStepGlobalizationUtil.globalize( + "cms.contentassets.ui.image_step.add_image"), + addCA); - /* ImageDisplayStep to display all already attached images */ - m_display = new ImageStepDisplay(this); // Component to display - setDisplayComponent(m_display); // all attached images. + /* ImageDisplayStep to display all already attached images */ + m_display = new ImageStepDisplay(this); // Component to display + setDisplayComponent(m_display); // all attached images. - Iterator imageComponents = m_add.getImageComponents(); - while (imageComponents.hasNext()) { - ImageComponent component = - (ImageComponent) imageComponents.next(); + Iterator imageComponents = m_add.getImageComponents(); + while (imageComponents.hasNext()) { + ImageComponent component = + (ImageComponent) imageComponents.next(); - addListeners(component.getForm(), - component.getSaveCancelSection().getCancelButton()); - } + addListeners(component.getForm(), + component.getSaveCancelSection().getCancelButton()); + } - m_parent.getList().addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - PageState state = event.getPageState(); - showDisplayPane(state); - } + m_parent.getList().addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + PageState state = event.getPageState(); + showDisplayPane(state); + } + }); + } - }); - } + @Override + public void register(Page p) { + super.register(p); - @Override - public void register(Page p) { - super.register(p); + p.addComponentStateParam(this, m_attachmentOID); + } - p.addComponentStateParam(this, m_attachmentOID); - } + /** + * @return the parent wizard + */ + public AuthoringKitWizard getParentWizard() { + return m_parent; + } - /** - * @return the parent wizard - */ - public AuthoringKitWizard getParentWizard() { - return m_parent; - } + /** + * @return The item selection model + */ + public ItemSelectionModel getItemSelectionModel() { + return m_itemSelection; + } - /** - * @return The item selection model - */ - public ItemSelectionModel getItemSelectionModel() { - return m_itemSelection; - } + /** + * @return The currently selected item, null if there isn't one. + */ + public ContentItem getItem(PageState ps) { + return m_itemSelection.getSelectedItem(ps); + } - /** - * @return The currently selected item, null if there isn't one. - */ - public ContentItem getItem(PageState ps) { - return m_itemSelection.getSelectedItem(ps); - } + /** + * @return The currently selected item, null if there isn't one. + */ + public ItemImageAttachment getAttachment(PageState ps) { + return (ItemImageAttachment) m_attachmentSelection.getSelectedAttachment(ps); + } - /** - * @return The currently selected item, null if there isn't one. - */ - public ItemImageAttachment getAttachment(PageState ps) { - return (ItemImageAttachment) m_attachmentSelection.getSelectedAttachment(ps); - } + private class AttachmentSelectionModel + extends AbstractSingleSelectionModel { - private class AttachmentSelectionModel - extends AbstractSingleSelectionModel { + private final RequestLocal m_attachment = new RequestLocal() { + @Override + protected Object initialValue(PageState ps) { + OID oid = (OID) getSelectedKey(ps); + if (null == oid) { + return null; + } - private final RequestLocal m_attachment = new RequestLocal() { - @Override - protected Object initialValue(PageState ps) { - OID oid = (OID) getSelectedKey(ps); - if (null == oid) { - return null; - } + return DomainObjectFactory.newInstance(oid); + } + }; - return DomainObjectFactory.newInstance(oid); - } + @Override + public Object getSelectedKey(PageState ps) { + OID oid = (OID) ps.getValue(m_attachmentOID); + if (null == oid) { + return null; + } - }; + return oid; + } - public Object getSelectedKey(PageState ps) { - OID oid = (OID) ps.getValue(m_attachmentOID); - if (null == oid) { - return null; - } + @Override + public void setSelectedKey(PageState ps, Object oid) { + m_attachment.set(ps, null); + ps.setValue(m_attachmentOID, oid); + } - return oid; - } + public ItemImageAttachment getSelectedAttachment(PageState ps) { + return (ItemImageAttachment) m_attachment.get(ps); + } - public void setSelectedKey(PageState ps, Object oid) { - m_attachment.set(ps, null); - ps.setValue(m_attachmentOID, oid); - } + public void setSelectedAttachment(PageState ps, + ItemImageAttachment attachment) { + setSelectedKey(ps, attachment); + m_attachment.set(ps, attachment); + } - public ItemImageAttachment getSelectedAttachment(PageState ps) { - return (ItemImageAttachment) m_attachment.get(ps); - } - - public void setSelectedAttachment(PageState ps, - ItemImageAttachment attachment) { - setSelectedKey(ps, attachment); - m_attachment.set(ps, attachment); - } - - public ParameterModel getStateParameter() { - return m_attachmentOID; - } - - } - - /** - * Show display pane. - * - * Also, reset the forms for reuse. - * - * @param state - */ - @Override - public void showDisplayPane(PageState state) { - super.showDisplayPane(state); - m_add.reset(state); - } + @Override + public ParameterModel getStateParameter() { + return m_attachmentOID; + } + } + /** + * Show display pane. + * + * Also, reset the forms for reuse. + * + * @param state + */ + @Override + public void showDisplayPane(PageState state) { + super.showDisplayPane(state); + m_add.reset(state); + } } diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepDisplay.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepDisplay.java index 9441a5f9d..a7b45976c 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepDisplay.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepDisplay.java @@ -15,7 +15,6 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - package com.arsdigita.cms.contentassets.ui; import com.arsdigita.bebop.BoxPanel; @@ -33,248 +32,424 @@ import com.arsdigita.bebop.list.ListModelBuilder; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ImageAsset; import com.arsdigita.cms.ReusableImageAsset; +import com.arsdigita.cms.Service; import com.arsdigita.cms.contentassets.ItemImageAttachment; import com.arsdigita.cms.contentassets.util.ImageStepGlobalizationUtil; import com.arsdigita.cms.ui.ImageDisplay; +import com.arsdigita.cms.util.GlobalizationUtil; +import com.arsdigita.domain.DomainObject; import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.persistence.DataCollection; +import com.arsdigita.persistence.DataObject; import com.arsdigita.persistence.OID; import com.arsdigita.util.LockableImpl; +import com.arsdigita.web.URL; import com.arsdigita.xml.Element; +import java.io.IOException; import javax.servlet.ServletException; import org.apache.log4j.Logger; /** * Component displays the currently attached images for an content item. It is - * part of the entry point image authoring step {@see ImageStep}. - * + * part of the entry point image authoring step { + * + * @see ImageStep}. + * * It creates a list of images including meta information (name, type, width, - * etc.), a link to remove from the list for each image and at the bottom a - * link to add another image. - * + * etc.), a link to remove from the list for each image and at the bottom a link + * to add another image. + * * @author unknown - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageStepDisplay extends SimpleContainer { - private static final Logger S_LOG = Logger.getLogger(ImageStepDisplay.class); + private static final Logger S_LOG = Logger.getLogger(ImageStepDisplay.class); + /** + * Represents invoking parent component + */ + private final ImageStep m_imageStep; + private ImageListModelBuilder m_listModelBuilder; + /** + * Name of the delete event + */ + private final static String DELETE = "deleteAttachment"; + private final static String MOVEUP = "moveAttachmentUp"; + private final static String MOVEDOWN = "moveAttachmentDown"; - /** Represents invoking parent component */ - private final ImageStep m_imageStep; + /** + * Constructor. + * + * @param step + */ + public ImageStepDisplay(ImageStep step) { + super(); - /** Name of the delete event */ - private final static String DELETE = "deleteAttachment"; + m_imageStep = step; - /** - * Constructor. - * - * @param step - */ - public ImageStepDisplay( ImageStep step ) { - super(); + /* Message to show in case no image has been attached yet. */ + Label mainLabel = new Label(ImageStepGlobalizationUtil.globalize( + "cms.contentassets.ui.image_step.no_image_attached")); + mainLabel.setFontWeight(Label.ITALIC); - m_imageStep = step; + m_listModelBuilder = new ImageListModelBuilder(); + List imageList = new List(m_listModelBuilder) { + @Override + public void respond(PageState ps) throws ServletException { + if (DELETE.equals(ps.getControlEventName())) { + DomainObjectFactory.newInstance(OID.valueOf(ps.getControlEventValue())).delete(); + // Regenerate sortkeys + m_listModelBuilder.getModel().regenSortKeys(ps); + } else if (MOVEUP.equals(ps.getControlEventName())) { + m_listModelBuilder.getModel().move(OID.valueOf(ps.getControlEventValue()), -1, ps); + } else if (MOVEDOWN.equals(ps.getControlEventName())) { + m_listModelBuilder.getModel().move(OID.valueOf(ps.getControlEventValue()), 1, ps); + } else { + super.respond(ps); + } + } + }; - /* Message to show in case no image has been attached yet. */ - Label mainLabel = new Label(ImageStepGlobalizationUtil.globalize( - "cms.contentassets.ui.image_step.no_image_attached")); - mainLabel.setFontWeight(Label.ITALIC); + imageList.setCellRenderer(new ImageListCellRenderer()); + imageList.setEmptyView(mainLabel); - List imageList = new List( new ImageListModelBuilder() ) { - @Override - public void respond( PageState ps ) throws ServletException { - if( DELETE.equals( ps.getControlEventName() ) ) { - String attachment = ps.getControlEventValue(); + add(imageList); // finally add the component + } - OID oid = OID.valueOf( attachment ); - DomainObjectFactory.newInstance( oid ).delete(); - } + /** + * Inner class + */ + private class ImageListModelBuilder extends LockableImpl + implements ListModelBuilder { - else { - super.respond( ps ); - } - } - }; - imageList.setCellRenderer( new ImageListCellRenderer() ); - imageList.setEmptyView( mainLabel ); + private ImageListModel m_listModel; - add( imageList ); // finally add the component - } + /** + * + * @param list + * @param ps + * @return + */ + @Override + public ListModel makeModel(List list, PageState ps) { + ContentItem item = m_imageStep.getItem(ps); - /** - * Inner class - */ - private class ImageListModelBuilder extends LockableImpl - implements ListModelBuilder { - /** - * - * @param list - * @param ps - * @return - */ - public ListModel makeModel( List list, PageState ps ) { - ContentItem item = m_imageStep.getItem( ps ); + DataCollection attachments = + ItemImageAttachment.getImageAttachments(item); + attachments.addPath(ItemImageAttachment.IMAGE + "." + + ReusableImageAsset.ID); + attachments.addPath(ItemImageAttachment.IMAGE + "." + + ReusableImageAsset.OBJECT_TYPE); + attachments.addPath(ItemImageAttachment.IMAGE + "." + + ReusableImageAsset.HEIGHT); + attachments.addPath(ItemImageAttachment.IMAGE + "." + + ReusableImageAsset.WIDTH); - DataCollection attachments = - ItemImageAttachment.getImageAttachments( item ); - attachments.addPath( ItemImageAttachment.IMAGE + "." + - ReusableImageAsset.ID ); - attachments.addPath( ItemImageAttachment.IMAGE + "." + - ReusableImageAsset.OBJECT_TYPE ); - attachments.addPath( ItemImageAttachment.IMAGE + "." + - ReusableImageAsset.HEIGHT ); - attachments.addPath( ItemImageAttachment.IMAGE + "." + - ReusableImageAsset.WIDTH ); + m_listModel = new ImageListModel(attachments); + return m_listModel; + } + protected ImageListModel getModel() { + return m_listModel; + } + } - return new ImageListModel( attachments ); - } - } + /** + * + */ + private class ImageListModel implements ListModel { - /** - * - */ - private class ImageListModel implements ListModel { + private final DataCollection m_attachments; - private final DataCollection m_attachments; + ImageListModel(DataCollection attachments) { + m_attachments = attachments; + } - ImageListModel( DataCollection attachments ) { - m_attachments = attachments; - } + @Override + public Object getElement() { + return DomainObjectFactory.newInstance(m_attachments.getDataObject()); + } - public Object getElement() { - return DomainObjectFactory.newInstance - ( m_attachments.getDataObject() ); - } + @Override + public String getKey() { + return m_attachments.getDataObject().getOID().toString(); + } - public String getKey() { - return m_attachments.getDataObject().getOID().toString(); - } + @Override + public boolean next() { + return m_attachments.next(); + } - public boolean next() { - return m_attachments.next(); - } - } + public boolean isFirst() { + return m_attachments.isFirst(); + } - /** - * - */ - private class ImageListCellRenderer implements ListCellRenderer { + public boolean isLast() { + return m_attachments.isLast(); + } - /** - * - * @param list - * @param state - * @param value - * @param key - * @param index - * @param isSelected - * @return - */ - public Component getComponent( final List list, PageState state, - Object value, String key, - int index, boolean isSelected ) { - final ItemImageAttachment attachment = (ItemImageAttachment) value; + /** + * Move an image's position inside the list. + * + * @param oid {@link OID} of the image to move + * @param move position steps (positive or negative) to move + * @param ps Current {@link PageState} + */ + protected void move(OID oid, int move, PageState ps) { + // Get the current ContentItem + ContentItem item = m_imageStep.getItem(ps); + // Get the collection of attached images + DataCollection attachments = ItemImageAttachment.getImageAttachments(item); - BoxPanel container = new BoxPanel( BoxPanel.VERTICAL ); - container.setBorder( 1 ); + // Always need an oid of the image to move + if (oid == null) { + throw new IllegalArgumentException("OID must not be null"); + } - // Add CMS ImageDisplay element to BoxPanel container an overwrite - // generateImagePropertiesXM to add attachment's meta data. - container.add( new ImageDisplay(null) { - @Override - protected void generateImagePropertiesXML( ImageAsset image, - PageState state, - Element element ) { - /* Use CMS ImageDisplay to display the image including * - * metadata as name, type, widht, height etc. */ - super.generateImagePropertiesXML(image, state, element); + // No move, nothing to do + if (move == 0) { + return; + } - // We check config here to see whether additional meta data - // as title and description are configured to be displayed. - // If it is, we display the description and title options - // TODO: Currently without Label, labels for each attribut - // are provided by the theme. Has to be refactored to - // provide labels in Java (including localization). - // Title and description - if displayed - have to be - // positioned above the image and its metadata. - if(ItemImageAttachment.getConfig() - .getIsImageStepDescriptionAndTitleShown()) { + // Find the image in the collection + while (attachments.next()) { + if (attachments.getDataObject().getOID().equals(oid)) { + break; + } + } + + // Throw an {@link IllegalArgumentxception} if the oid was not found + if (!attachments.getDataObject().getOID().equals(oid)) { + throw new IllegalArgumentException("OID " + oid + " is not in collection"); + } + + // Get the image to move and test if it is really an ItemImageAttachment + DomainObject sortDomainObject = DomainObjectFactory.newInstance(attachments.getDataObject()); + if (sortDomainObject instanceof ItemImageAttachment) { + + // Change the sortKey of the ItemImageAttachment to the desired + // value but respect bounds of the current list + int newSortKey = Math.max(1, + Math.min((int) attachments.size(), + ((ItemImageAttachment) sortDomainObject).getSortKey() + move)); + ((ItemImageAttachment) sortDomainObject).setSortKey(newSortKey); + ((ItemImageAttachment) sortDomainObject).save(); + + // Now, move all the object between the original position and the + // new postition one step in the nessecary direction + if (move < 0) { + while (attachments.previous() && move < 0) { + DomainObject domainObject = DomainObjectFactory.newInstance(attachments.getDataObject()); + if (domainObject instanceof ItemImageAttachment) { + ((ItemImageAttachment) domainObject).setSortKey( + ((ItemImageAttachment) domainObject).getSortKey() + 1); + ((ItemImageAttachment) domainObject).save(); + move++; + } + } + } + if (move > 0) { + while (attachments.next() && move > 0) { + DomainObject domainObject = DomainObjectFactory.newInstance(attachments.getDataObject()); + if (domainObject instanceof ItemImageAttachment) { + ((ItemImageAttachment) domainObject).setSortKey( + ((ItemImageAttachment) domainObject).getSortKey() - 1); + ((ItemImageAttachment) domainObject).save(); + move--; + } + } + } + } + + // close the collection manually to avoid warnings because the list + // will not be closed automatically + attachments.close(); + } + + /** + * Reorganize the sortKeys after removing an item. + * + * @param ps The current {@link PageState} + */ + protected void regenSortKeys(PageState ps) { + // Get the current ContentItem + ContentItem item = m_imageStep.getItem(ps); + // Get the collection of attached images + DataCollection attachments = ItemImageAttachment.getImageAttachments(item); + + // Current Position + int pos = 0; + // Iterate through all items and set item sortKey to pos + while (attachments.next()) { + pos++; + DomainObject domainObject = DomainObjectFactory.newInstance(attachments.getDataObject()); + if (domainObject instanceof ItemImageAttachment) { + int sortKey = ((ItemImageAttachment) domainObject).getSortKey(); + if (sortKey != pos) { + ((ItemImageAttachment) domainObject).setSortKey(pos); + domainObject.save(); + } + } + } + } + } + + /** + * + */ + private class ImageListCellRenderer implements ListCellRenderer { + + /** + * + * @param list + * @param state + * @param value + * @param key + * @param index + * @param isSelected + * @return + */ + @Override + public Component getComponent(final List list, PageState state, + Object value, String key, + int index, boolean isSelected) { + final ItemImageAttachment attachment = (ItemImageAttachment) value; + + BoxPanel container = new BoxPanel(BoxPanel.VERTICAL); + container.setBorder(1); + + // Add CMS ImageDisplay element to BoxPanel container an overwrite + // generateImagePropertiesXM to add attachment's meta data. + container.add(new ImageDisplay(null) { + @Override + protected void generateImagePropertiesXML(ImageAsset image, + PageState state, + Element element) { + /* Use CMS ImageDisplay to display the image including * + * metadata as name, type, widht, height etc. */ + super.generateImagePropertiesXML(image, state, element); + + // We check config here to see whether additional meta data + // as title and description are configured to be displayed. + // If it is, we display the description and title options + // TODO: Currently without Label, labels for each attribut + // are provided by the theme. Has to be refactored to + // provide labels in Java (including localization). + // Title and description - if displayed - have to be + // positioned above the image and its metadata. + if (ItemImageAttachment.getConfig() + .getIsImageStepDescriptionAndTitleShown()) { String description = attachment.getDescription(); if (description != null) { element.addAttribute("description", description); } String title = attachment.getTitle(); - if (title!= null) { + if (title != null) { element.addAttribute("title", title); } } + element.addAttribute("caption_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.caption") + .localize()); + element.addAttribute("caption", attachment.getCaption()); - } + element.addAttribute("context_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.use_context") + .localize()); + String useContext = attachment.getUseContext(); + if (null == useContext) { + element.addAttribute("context", (String) GlobalizationUtil.globalize( + "cms.ui.unknown") + .localize()); + } else { + element.addAttribute("context", useContext); + } - @Override - protected ImageAsset getImageAsset( PageState ps ) { - return attachment.getImage(); - } - } ); + } - /* Create a box panel beloy the image to display the caption */ - BoxPanel captionPanel = new BoxPanel( BoxPanel.HORIZONTAL ); - - captionPanel.add(new Label(ImageStepGlobalizationUtil.globalize( - "cms.contentasset.image.ui.caption"))); - Label captionText = new Label( new PrintListener() { - public void prepare( PrintEvent ev ) { - Label l = (Label) ev.getTarget(); - String caption = attachment.getCaption(); - if( null == caption ) { - l.setLabel( ImageStepGlobalizationUtil.globalize( - "cms.ui.unknown") ); - } else { - l.setLabel( caption ); - } - } - } ); - captionText.setOutputEscaping( false ); - captionPanel.add( captionText ); - container.add( captionPanel ); + @Override + protected ImageAsset getImageAsset(PageState ps) { + return attachment.getImage(); + } + }); - /* Create a box panel beloy the image to display use context*/ - BoxPanel useContextPanel = new BoxPanel( BoxPanel.HORIZONTAL ); - - useContextPanel.add(new Label( ImageStepGlobalizationUtil.globalize( - "cms.contentasset.image.ui.use_context") ) ); - Label useContextLabel = new Label( new PrintListener() { - public void prepare( PrintEvent ev ) { - Label l = (Label) ev.getTarget(); - String useContext = attachment.getUseContext(); - if( null == useContext ) { - l.setLabel( ImageStepGlobalizationUtil.globalize( - "cms.ui.unknown") ); - } else { - l.setLabel( useContext ); - } - } - } ); - useContextLabel.setOutputEscaping( false ); - useContextPanel.add( useContextLabel ); - container.add( useContextPanel ); + /* Adds links to move and remove the image in a separate container element */ + if (!((ImageListModel) list.getModel(state)).isFirst()) { + ControlLink moveUpLink = new ControlLink(new Label( + ImageStepGlobalizationUtil.globalize( + "cms.contentassets.ui.image_step.move_attached_image_up"))) { + @Override + public void setControlEvent(PageState ps) { + String oid = ps.getControlEventValue(); + ps.setControlEvent(list, MOVEUP, oid); + } - /* Add a link to remove the image in a separate container elemet */ - ControlLink deleteLink = new ControlLink(new Label( - ImageStepGlobalizationUtil.globalize( - "cms.contentassets.ui.image_step.remove_attached_image") )) { - @Override - public void setControlEvent( PageState ps ) { - String oid = ps.getControlEventValue(); - ps.setControlEvent( list, DELETE, oid ); - } - }; - container.add( deleteLink ); + // Override generateURL to prevent deleting of the page state + @Override + protected void generateURL(PageState state, Element parent) { + setControlEvent(state); + try { + parent.addAttribute("href", state.stateAsURL()); + } catch (IOException e) { + parent.addAttribute("href", ""); + } + exportAttributes(parent); + } + }; + container.add(moveUpLink); + } - return container; - } - } + if (!((ImageListModel) list.getModel(state)).isLast()) { + ControlLink moveDownLink = new ControlLink(new Label( + ImageStepGlobalizationUtil.globalize( + "cms.contentassets.ui.image_step.move_attached_image_down"))) { + @Override + public void setControlEvent(PageState ps) { + String oid = ps.getControlEventValue(); + ps.setControlEvent(list, MOVEDOWN, oid); + } + + // Override generateURL to prevent deleting of the page state + @Override + protected void generateURL(PageState state, Element parent) { + setControlEvent(state); + try { + parent.addAttribute("href", state.stateAsURL()); + } catch (IOException e) { + parent.addAttribute("href", ""); + } + exportAttributes(parent); + } + }; + container.add(moveDownLink); + } + + ControlLink deleteLink = new ControlLink(new Label( + ImageStepGlobalizationUtil.globalize( + "cms.contentassets.ui.image_step.remove_attached_image"))) { + @Override + public void setControlEvent(PageState ps) { + String oid = ps.getControlEventValue(); + ps.setControlEvent(list, DELETE, oid); + } + + // Override generateURL to prevent deleting of the page state + @Override + protected void generateURL(PageState state, Element parent) { + setControlEvent(state); + try { + parent.addAttribute("href", state.stateAsURL()); + } catch (IOException e) { + parent.addAttribute("href", ""); + } + exportAttributes(parent); + } + }; + container.add(deleteLink); + + return container; + } + } } diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepEdit.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepEdit.java index fdd818421..0373f9db0 100755 --- a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepEdit.java +++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepEdit.java @@ -53,7 +53,7 @@ import org.apache.log4j.Logger; * It doesn't engage a lot of its own logik but uses CMS default image classes. * * @author unknown - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageStepEdit extends SimpleContainer implements Resettable { diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources.properties index 3fe4b3859..63e9f4d5e 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources.properties @@ -1062,3 +1062,4 @@ cms.ui.images=Images cms.ui.folder.additionalInfo=Info cms.ui.section.new_section_root_category=Root category of the new Content Section cms.ui.admin_center=Admin Center +cms.contentasset.image.ui.display.dimensions=Dimensions (width x height): diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties index 2dc954180..e4b073682 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties @@ -1042,7 +1042,7 @@ cms.contentasset.image.ui.table.header_action_select=Aktion cms.contentasset.image.ui.table.link_delete=Aus dem System endg\u00fcltig l\u00f6schen cms.contentasset.image.ui.table.header_action_delete=Aus dem System l\u00f6schen cms.contentasset.image.ui.display.name=Name: -cms.contentasset.image.ui.display.type=Bild Typ: +cms.contentasset.image.ui.display.type=Bild-Typ: cms.contentasset.image.ui.display.width=Breite: cms.contentasset.image.ui.display.height=H\u00f6he: cms.ui.description_hint=Eine kurze Charakterisierung des Dokumentes, nach M\u00f6glichkeit nicht l\u00e4nger als 2-3 S\u00e4tze. Standardm\u00e4\u00dfig wird die Beschreibung zusammen mit dem Titel in allen Dokumentenliste angezeigt, um so Seiten mit hohem Informationsgehalt zu erzeugen. @@ -1056,3 +1056,4 @@ cms.ui.images=Bilder cms.ui.folder.additionalInfo=Info cms.ui.section.new_section_root_category=Kategoriensystem der neuen Content Section cms.ui.admin_center=Admin Center +cms.contentasset.image.ui.display.dimensions=Ma\u00dfe (Breite x H\u00f6he): diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties index c59c6357d..4a556892c 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources_en_GB.properties @@ -110,3 +110,4 @@ cms.ui.images=Images cms.ui.folder.additionalInfo= cms.ui.section.new_section_root_category= cms.ui.admin_center=Admin Center +cms.contentasset.image.ui.display.dimensions=Dimensions (width x height): diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties index 4e1dbbce0..674db72e4 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties @@ -584,3 +584,4 @@ cms.ui.images=Images cms.ui.folder.additionalInfo= cms.ui.section.new_section_root_category= cms.ui.admin_center=Admin Center +cms.contentasset.image.ui.display.dimensions=Dimensions (width x height): diff --git a/ccm-cms/src/com/arsdigita/cms/CachedImage.java b/ccm-cms/src/com/arsdigita/cms/CachedImage.java index ed21b94e1..c20a615b1 100644 --- a/ccm-cms/src/com/arsdigita/cms/CachedImage.java +++ b/ccm-cms/src/com/arsdigita/cms/CachedImage.java @@ -22,7 +22,7 @@ import org.imgscalr.Scalr; * cache of {@link BaseImage}. Also, this class is able to create server-side * resized versions of ImageAssets. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class CachedImage { diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSection.java b/ccm-cms/src/com/arsdigita/cms/ContentSection.java index 8a884a14a..941e3771c 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentSection.java @@ -90,7 +90,7 @@ import org.apache.log4j.Logger; * * @author Michael Pih * @author Jack Chung - * @author Sören Bernstein (quasi@barkhof.uni-bremen.de) + * @author Sören Bernstein * @version $Revision: #37 $ $DateTime: 2004/08/17 23:15:09 $ * @version $Id: ContentSection.java 2305 2012-05-01 12:26:33Z pboy $ */ diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java index 67511bf39..8a51db9c9 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentSectionServlet.java @@ -97,7 +97,7 @@ import org.apache.log4j.Logger; * folders to jsp templates. * * @author unknown - * @author Sören Bernstein + * @author Sören Bernstein * @author Peter Boy */ public class ContentSectionServlet extends BaseApplicationServlet { diff --git a/ccm-cms/src/com/arsdigita/cms/ImageAsset.java b/ccm-cms/src/com/arsdigita/cms/ImageAsset.java index 48658256c..1c5c7e350 100755 --- a/ccm-cms/src/com/arsdigita/cms/ImageAsset.java +++ b/ccm-cms/src/com/arsdigita/cms/ImageAsset.java @@ -52,7 +52,7 @@ import org.apache.log4j.Logger; * * @author Jack Chung * @author Stanislav Freidin - * @author Sören Bernstein + * @author Sören Bernstein * * @version $Id: ImageAsset.java 2225 2011-08-02 18:53:56Z pboy $ */ diff --git a/ccm-cms/src/com/arsdigita/cms/LanguageInvariantContentItem.java b/ccm-cms/src/com/arsdigita/cms/LanguageInvariantContentItem.java index 3bfef110e..870a8df01 100644 --- a/ccm-cms/src/com/arsdigita/cms/LanguageInvariantContentItem.java +++ b/ccm-cms/src/com/arsdigita/cms/LanguageInvariantContentItem.java @@ -9,7 +9,7 @@ package com.arsdigita.cms; * Content Items implementing this interface are be language invariant, if * isLanguageInvariant returns true * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public interface LanguageInvariantContentItem { diff --git a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java index 241fb7df4..7b215756c 100644 --- a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java @@ -40,7 +40,7 @@ import org.apache.log4j.Logger; * to be modifiable must be included in Loader class itself! * * @author pb - * @author Sören Bernstein (quasi@barkhof.uni-bremen.de) + * @author Sören Bernstein * @version $Id: LoaderConfig.java $ */ public final class LoaderConfig extends AbstractConfig { diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java index 7e4de4db9..f6987b7a7 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java @@ -33,7 +33,7 @@ import org.apache.log4j.Logger; * Configures parameter which are not persisted in the database and may be * changes during each startup of the system. * @author pb - * @author Sören Bernstein (quasi@barkhof.uni-bremen.de) + * @author Sören Bernstein */ public final class ContentSectionConfig extends AbstractConfig { diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java index c0d096edc..baeabd10d 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java @@ -63,7 +63,7 @@ import org.xml.sax.helpers.DefaultHandler; * into the database. * * @author Peter Boy (pboy@barkhof.uni-bremen.de) - * @author Sören Bernstein (quasi@barkhof.uni-bremen.de) + * @author Sören Bernstein * @author Jon Orris (jorris@redhat.com) * @version $Id: $ */ diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/AbstractContentTypeLoader.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/AbstractContentTypeLoader.java index 8457e0d8e..0e7e7ac76 100755 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/AbstractContentTypeLoader.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/AbstractContentTypeLoader.java @@ -61,7 +61,7 @@ import org.apache.log4j.Logger; * registry object (file). * * @author Rafael H. Schloming <rhs@mit.edu> - * @authro Sören Bernstein (quasi@barkhof.uni-bremen.de) + * @author Sören Bernstein * @version $Revision: #754 $ $Date: 2005/09/02 $ $Author: pboy $ **/ public abstract class AbstractContentTypeLoader extends PackageLoader { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericAddress.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericAddress.java index 59b647754..978cc657e 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericAddress.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericAddress.java @@ -40,7 +40,7 @@ import org.apache.log4j.Logger; *

This class extends {@link com.arsdigita.cms.ContentItem content item} and * adds extended attributes specific for an not country specific address:

* - * @author Sören Bernstein + * @author Sören Bernstein **/ public class GenericAddress extends ContentPage { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactConfig.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactConfig.java index e838baed1..15a4318bf 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactConfig.java @@ -11,7 +11,7 @@ import org.apache.log4j.Logger; /** * Stores the configuration record for the generic contact. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein */ public final class GenericContactConfig extends AbstractConfig { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactEntryKeys.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactEntryKeys.java index ffe321b8f..8b2b30cfc 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactEntryKeys.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericContactEntryKeys.java @@ -10,7 +10,7 @@ import com.arsdigita.persistence.DataCollection; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class GenericContactEntryKeys extends RelationAttributeCollection { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericPerson.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericPerson.java index ba9f95cf7..8fb3f29bb 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericPerson.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/GenericPerson.java @@ -37,7 +37,7 @@ import java.util.StringTokenizer; /** * Basic GenericPerson Contenttype for OpenCCM. * - * @author Sören Bernstein + * @author Sören Bernstein * @author Jens Pelzetter */ public class GenericPerson extends ContentPage implements diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/Link.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/Link.java index 70f8b70b1..896177802 100755 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/Link.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/Link.java @@ -50,7 +50,7 @@ import org.apache.log4j.Logger; * * @version $Revision: #7 $ $Date: 2004/08/17 $ * @author Nobuko Asakai (nasakai@redhat.com) - * @author Sören Bernstein (Quasimodo) + * @author Sören Bernstein */ public class Link extends ACSObject { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/LinkTraversalAdapter.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/LinkTraversalAdapter.java index 0679294e6..0c1ad3b46 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/LinkTraversalAdapter.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/LinkTraversalAdapter.java @@ -32,7 +32,7 @@ import com.arsdigita.globalization.GlobalizationHelper; * This is a modified copy of ContentItemTraversalAdapter to make the * Link-Objects aware of multilingual items (ContentBundle) * - * @author Sören Bernstein (Quasimodo) + * @author Sören Bernstein */ public class LinkTraversalAdapter extends ContentItemTraversalAdapter { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericAddressPropertyForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericAddressPropertyForm.java index df4a36d4e..b40dea65a 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericAddressPropertyForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericAddressPropertyForm.java @@ -49,7 +49,7 @@ import org.apache.log4j.Logger; * Form to edit the properties of a address. * * @author: Jens Pelzetter - * @author: Sören Bernstein + * @author Sören Bernstein */ public class GenericAddressPropertyForm extends BasicPageForm implements FormProcessListener, diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntriesTable.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntriesTable.java index 10a342c9a..e2d476309 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntriesTable.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntriesTable.java @@ -46,7 +46,7 @@ import java.math.BigDecimal; /** * Lists all existing contact entries for a selected contact. * - * @author Sören Bernstein (quasimodo) quasi@barkhof.uni-bremen.de + * @author Sören Bernstein */ public class GenericContactEntriesTable extends Table implements TableActionListener { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntryAddForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntryAddForm.java index 6bc2fbf9f..4cfefe989 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntryAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactEntryAddForm.java @@ -40,7 +40,7 @@ import com.arsdigita.globalization.GlobalizationHelper; import org.apache.log4j.Logger; /** - * @author Sören Bernstein (quasimodo) quasi@barkhof.uni-bremen.de + * @author Sören Bernstein */ public class GenericContactEntryAddForm extends BasicItemForm { private static final Logger s_log = Logger.getLogger(GenericContactEntryAddForm.class); diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactPropertiesStep.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactPropertiesStep.java index 1a667e5ed..9d84589dd 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactPropertiesStep.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactPropertiesStep.java @@ -47,7 +47,7 @@ import org.apache.log4j.Logger; * - Address * - Various contact entries. * - * @author quasi + * @author quasi */ public class GenericContactPropertiesStep extends SimpleEditStep { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeAddForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeAddForm.java index 6385b784f..dfbdaa3a7 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeAddForm.java @@ -48,7 +48,7 @@ import org.apache.log4j.Logger; * This class is part of the admin GUI of CCM and extends the standard form * in order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein */ public class GenericContactTypeAddForm extends BasicItemForm { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypePropertiesStep.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypePropertiesStep.java index 00b79ffbf..3cab214fc 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypePropertiesStep.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypePropertiesStep.java @@ -26,7 +26,7 @@ import com.arsdigita.cms.ui.authoring.SimpleEditStep; import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess; /** - * @author Sören Bernstein + * @author Sören Bernstein */ public class GenericContactTypePropertiesStep extends SimpleEditStep { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeTable.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeTable.java index 19119ca20..ad6c47270 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeTable.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericContactTypeTable.java @@ -43,7 +43,7 @@ import java.math.BigDecimal; /** * * - * @author Sören Bernstein (quasimodo) quasi@barkhof.uni-bremen.de + * @author Sören Bernstein */ public class GenericContactTypeTable extends Table implements TableActionListener { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactAddForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactAddForm.java index 4b6c5fc80..31517f1db 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactAddForm.java @@ -52,7 +52,7 @@ import org.apache.log4j.Logger; * This class is part of the admin GUI of CCM and extends the standard form * in order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein */ public class GenericPersonContactAddForm extends BasicItemForm { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactPropertiesStep.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactPropertiesStep.java index b6ed8ad1b..0d418b8b4 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactPropertiesStep.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactPropertiesStep.java @@ -26,7 +26,7 @@ import com.arsdigita.cms.ui.authoring.SimpleEditStep; import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess; /** - * @author Sören Bernstein + * @author Sören Bernstein */ public class GenericPersonContactPropertiesStep extends SimpleEditStep { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactTable.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactTable.java index b127cbea8..c00990c9e 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactTable.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonContactTable.java @@ -52,7 +52,7 @@ import org.apache.log4j.Logger; /** * Lists all existing contact entries for a selected contact. * - * @author Sören Bernstein (quasimodo) quasi@barkhof.uni-bremen.de + * @author Sören Bernstein */ public class GenericPersonContactTable extends Table implements TableActionListener { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonCreate.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonCreate.java index 168f3c312..1d0406e78 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonCreate.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericPersonCreate.java @@ -43,7 +43,7 @@ import java.util.Date; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class GenericPersonCreate extends PageCreate { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java index 73c698cab..af5b56df1 100755 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java @@ -63,7 +63,7 @@ import org.apache.log4j.Logger; * * @version $Revision: #5 $ $Date: 2004/08/17 $ * @author Nobuko Asakai (nasakai@redhat.com) - * @author Sören Bernstein (sbernstein@zes.uni-bremen.de) + * @author Sören Bernstein */ public class LinkPropertyForm extends FormSection implements FormInitListener, FormProcessListener, diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java index 94970c533..81b9c90da 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java @@ -48,7 +48,7 @@ import org.apache.log4j.Logger; * * @author Stanislav Freidin (sfreidin@arsdigita.com) * @author Michael Pih (pihman@arsdigita.com) - * @author Sören Bernstein + * @author Sören Bernstein * @version $Revision: #20 $ $DateTime: 2004/08/17 23:15:09 $ * @version $Id: BaseImage.java 1571 2007-04-20 15:57:54Z apevec $ */ diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java index 4510c1bd6..81448a61a 100644 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java @@ -7,7 +7,7 @@ package com.arsdigita.cms.dispatcher; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class DownloadImage extends BaseImage { diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java index 3c37ac595..981b14e45 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java @@ -6,7 +6,7 @@ package com.arsdigita.cms.dispatcher; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class StreamImage extends BaseImage { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java index f67b18836..6eaac5178 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/CMSItemSearchPage.java @@ -51,7 +51,7 @@ import javax.servlet.http.HttpServletResponse; * The Item Search page. * * @author Scott Seago (scott@arsdigita.com) - * @author Sören Bernstein (sbernstein@quasiweb.de) + * @author Sören Bernstein * @author Jens Pelzetter (jens@jp-digital.de) */ public class CMSItemSearchPage extends CMSApplicationPage { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ContentItemPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ContentItemPage.java index d5675adcb..d50485781 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ContentItemPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ContentItemPage.java @@ -69,7 +69,7 @@ import org.apache.log4j.Logger; * @author Michael Pih * @author Stanislav Freidin <sfreidin@redhat.com> * @author Jack Chung - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * * @version $Id: ContentItemPage.java 2245 2011-11-15 08:03:57Z pboy $ */ @@ -339,7 +339,7 @@ public class ContentItemPage extends CMSPage implements ActionListener { getConfig().getHideTemplatesTab()); } - // Added by: Sören Bernstein + // Added by: Sören Bernstein // If the content item is a language invariant content item, don't show // the language pane if (item instanceof LanguageInvariantContentItem) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/DefaultImageBrowserModelBuilder.java b/ccm-cms/src/com/arsdigita/cms/ui/DefaultImageBrowserModelBuilder.java index b136a2e23..5192d1321 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/DefaultImageBrowserModelBuilder.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/DefaultImageBrowserModelBuilder.java @@ -37,7 +37,7 @@ import com.arsdigita.util.LockableImpl; * builder will return an {@link EmptyImageBrowserModel} * * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * @version $Id: DefaultImageBrowserModelBuilder.java 1940 2009-05-29 07:15:05Z * terry $ */ diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageBrowser.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageBrowser.java index 16c1af1c1..ea3c44245 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageBrowser.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageBrowser.java @@ -63,7 +63,7 @@ import org.apache.log4j.Logger; * * * @author Stanislav Freidin - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * @version $Id: ImageBrowser.java 1940 2009-05-29 07:15:05Z terry $ */ public class ImageBrowser extends Table { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageChooser.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageChooser.java index 6084f12fd..1436f2fbc 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageChooser.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageChooser.java @@ -45,7 +45,7 @@ import com.arsdigita.cms.util.GlobalizationUtil; * by keyword * * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * @version $Id: ImageChooser.java 1940 2009-05-29 07:15:05Z terry $ */ public class ImageChooser extends BoxPanel { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponent.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponent.java index 0a843955c..a718c9ef7 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponent.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponent.java @@ -15,7 +15,7 @@ import com.arsdigita.cms.ReusableImageAsset; * All components for image handling (like {@link ImageLibraryComponent} or * {@link ImageUploadComponent}) should implement this interface. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public interface ImageComponent { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAbstractListener.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAbstractListener.java index 21a395281..d61d851ff 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAbstractListener.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAbstractListener.java @@ -19,80 +19,85 @@ import org.apache.log4j.Logger; /** * An abstract listener for {@link ImageComponent}. - * - * This listener provides the base implementation which is shared between all + * + * This listener provides the base implementation which is shared between all * listeners of this kind. - * + * * This listerner is used by {@link ImageSelectPage}. - * - * @author Sören Bernstein (quasimodo) + * + * @author Sören Bernstein */ -public abstract class ImageComponentAbstractListener implements FormInitListener, - FormProcessListener, - FormSubmissionListener { +public abstract class ImageComponentAbstractListener implements FormInitListener, + FormProcessListener, + FormSubmissionListener { - private static final Logger s_log = Logger.getLogger( - ImageComponentSelectListener.class); - MapComponentSelectionModel m_imageComponent; + private static final Logger s_log = Logger.getLogger( + ImageComponentSelectListener.class); + MapComponentSelectionModel m_imageComponent; - public ImageComponentAbstractListener(MapComponentSelectionModel imageComponent) { - super(); - m_imageComponent = imageComponent; - } + public ImageComponentAbstractListener(MapComponentSelectionModel imageComponent) { + super(); + m_imageComponent = imageComponent; + } - public void init(FormSectionEvent event) - throws FormProcessException { - PageState ps = event.getPageState(); - if (!m_imageComponent.isSelected(ps)) { - setImageComponent(ps, ImageComponent.LIBRARY); - } - } + @Override + public void init(FormSectionEvent event) + throws FormProcessException { + PageState ps = event.getPageState(); + if (!m_imageComponent.isSelected(ps)) { + setImageComponent(ps, ImageComponent.LIBRARY); + } + } - /** - * Call {@link #cancelled(com.arsdigita.bebop.PageState)} if the cancel button - * was pressed. - * - * @param event the {@link FormSectionEvent} - * @throws FormProcessException - */ - public void submitted(FormSectionEvent event) throws FormProcessException { - PageState ps = event.getPageState(); - ImageComponent component = getImageComponent(ps); + /** + * Call {@link #cancelled(com.arsdigita.bebop.PageState)} if the cancel + * button was pressed. + * + * @param event the {@link FormSectionEvent} + * @throws FormProcessException + */ + @Override + public void submitted(FormSectionEvent event) throws FormProcessException { + PageState ps = event.getPageState(); + ImageComponent component = getImageComponent(ps); - if(component.getSaveCancelSection().getCancelButton().isSelected(ps)) { - cancelled(ps); - } - } + if (component.getSaveCancelSection().getCancelButton().isSelected(ps)) { + cancelled(ps); + } + } - /** - * Call {@link #processImage(com.arsdigita.bebop.event.FormSectionEvent, - * com.arsdigita.bebop.PageState, com.arsdigita.cms.ui.ImageComponent, - * com.arsdigita.cms.ReusableImageAsset) } - * if the save button was pressed. - * - * @param event the {@link FormSectionEvent} - * @throws FormProcessException - */ - public void process(FormSectionEvent event) throws FormProcessException { - PageState ps = event.getPageState(); - ImageComponent component = getImageComponent(ps); + /** + * Call {@link #processImage(com.arsdigita.bebop.event.FormSectionEvent, + * com.arsdigita.bebop.PageState, com.arsdigita.cms.ui.ImageComponent, + * com.arsdigita.cms.ReusableImageAsset) } + * if the save button was pressed. + * + * @param event the {@link FormSectionEvent} + * @throws FormProcessException + */ + @Override + public void process(FormSectionEvent event) throws FormProcessException { + PageState ps = event.getPageState(); + ImageComponent component = getImageComponent(ps); - if (!component.getSaveCancelSection().getSaveButton().isSelected(ps)) { - return; - } + if (!component.getSaveCancelSection().getSaveButton().isSelected(ps)) { + return; + } - ReusableImageAsset image = component.getImage(event); + ReusableImageAsset image = component.getImage(event); - processImage(event, ps, component, image); - } + processImage(event, ps, component, image); + } + /** + * To be overridden by child if neccessary. + * + * @param ps + */ + protected void cancelled(PageState ps) { + } - /** - * To be overridden by child if neccessary. - * - * @param ps - */ - protected void cancelled(PageState ps) {}; + ; /** * Process the input. @@ -104,45 +109,45 @@ public abstract class ImageComponentAbstractListener implements FormInitListener */ protected abstract void processImage(FormSectionEvent event, PageState ps, ImageComponent component, ReusableImageAsset image); - protected ImageComponent getImageComponent(PageState ps) { - if (!m_imageComponent.isSelected(ps)) { - if (s_log.isDebugEnabled()) { - s_log.debug("No component selected"); - s_log.debug("Selected: " + m_imageComponent.getComponent(ps)); - } + protected ImageComponent getImageComponent(PageState ps) { + if (!m_imageComponent.isSelected(ps)) { + if (s_log.isDebugEnabled()) { + s_log.debug("No component selected"); + s_log.debug("Selected: " + m_imageComponent.getComponent(ps)); + } - m_imageComponent.setSelectedKey(ps, ImageComponent.UPLOAD); - } + m_imageComponent.setSelectedKey(ps, ImageComponent.UPLOAD); + } - return (ImageComponent) m_imageComponent.getComponent(ps); + return (ImageComponent) m_imageComponent.getComponent(ps); - } + } - /** - * Sets the active component - * - * @param ps Page state - * @param activeKey the key of the active component - */ - protected void setImageComponent(PageState ps, final String activeKey) { + /** + * Sets the active component + * + * @param ps Page state + * @param activeKey the key of the active component + */ + protected void setImageComponent(PageState ps, final String activeKey) { - if (s_log.isDebugEnabled()) { - s_log.debug("Selected component: " + activeKey); - } + if (s_log.isDebugEnabled()) { + s_log.debug("Selected component: " + activeKey); + } - Map componentsMap = m_imageComponent.getComponentsMap(); - Iterator i = componentsMap.keySet().iterator(); - while (i.hasNext()) { - Object key = i.next(); - Component component = (Component) componentsMap.get(key); + Map componentsMap = m_imageComponent.getComponentsMap(); + Iterator i = componentsMap.keySet().iterator(); + while (i.hasNext()) { + Object key = i.next(); + Component component = (Component) componentsMap.get(key); - boolean isVisible = activeKey.equals(key); + boolean isVisible = activeKey.equals(key); - if (s_log.isDebugEnabled()) { - s_log.debug("Key: " + key + "; Visibility: " + isVisible); - } + if (s_log.isDebugEnabled()) { + s_log.debug("Key: " + key + "; Visibility: " + isVisible); + } - ps.setVisible(component, isVisible); - } - } + ps.setVisible(component, isVisible); + } + } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAdminListener.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAdminListener.java index 738b2c90b..9da2d993b 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAdminListener.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentAdminListener.java @@ -17,7 +17,7 @@ import com.arsdigita.toolbox.ui.ComponentMap; * * This listerner is used by {@link ImagesPane}. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ class ImageComponentAdminListener extends ImageComponentAbstractListener implements ActionListener { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentSelectListener.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentSelectListener.java index 06b147633..11c8fa1ca 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentSelectListener.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageComponentSelectListener.java @@ -15,7 +15,7 @@ import org.apache.log4j.Logger; * * This listerner is used by {@link ImageSelectPage}. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageComponentSelectListener extends ImageComponentAbstractListener { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageDisplay.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageDisplay.java index 39226b381..11e6c0f9f 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageDisplay.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageDisplay.java @@ -31,10 +31,9 @@ import com.arsdigita.web.URL; import com.arsdigita.xml.Element; import java.math.BigDecimal; - /** - * Displays a single ImageAsset, showing its image, width, height, - * name and mime-type. + * Displays a single ImageAsset, showing its image, width, height, name and + * mime-type. * * @author Michael Pih (pihman@arsdigita.com) * @author Stanislav Freidin (sfreidin@arsdigita.com) @@ -42,113 +41,117 @@ import java.math.BigDecimal; */ public class ImageDisplay extends SimpleComponent { - private final ItemSelectionModel m_item; + private final ItemSelectionModel m_item; - /** - * Construct a new ImageDisplay - * - * @param m The {@link ItemSelectionModel} which will supply - * this component with the {@link ImageAsset} - */ - public ImageDisplay(ItemSelectionModel m) { - super(); - m_item = m; - } + /** + * Construct a new ImageDisplay + * + * @param m The {@link ItemSelectionModel} which will supply this component + * with the {@link ImageAsset} + */ + public ImageDisplay(ItemSelectionModel m) { + super(); + m_item = m; + } - /** - * @return the {@link ItemSelectionModel} which supplies this - * component with the {@link ImageAsset} - */ - public final ItemSelectionModel getImageSelectionModel() { - return m_item; - } + /** + * @return the {@link ItemSelectionModel} which supplies this component with + * the {@link ImageAsset} + */ + public final ItemSelectionModel getImageSelectionModel() { + return m_item; + } - /** - * - * @param state - * @param parent - */ - @Override - public void generateXML(PageState state, Element parent) { - if ( isVisible(state) ) { + /** + * + * @param state + * @param parent + */ + @Override + public void generateXML(PageState state, Element parent) { + if (isVisible(state)) { - ImageAsset image = getImageAsset(state); + ImageAsset image = getImageAsset(state); - if (image == null) { - return; - } + if (image == null) { + return; + } - Element element = new Element("cms:imageDisplay", CMS.CMS_XML_NS); + Element element = new Element("cms:imageDisplay", CMS.CMS_XML_NS); - if (image != null) { - generateImagePropertiesXML(image, state, element); - } + if (image != null) { + generateImagePropertiesXML(image, state, element); + } - exportAttributes(element); - parent.addContent(element); - } - } + exportAttributes(element); + parent.addContent(element); + } + } - /** - * Generates the property xml. - * - * @param image - * @param state - * @param element - */ - protected void generateImagePropertiesXML(ImageAsset image, - PageState state, - Element element) { + /** + * Generates the property xml. + * + * @param image + * @param state + * @param element + */ + protected void generateImagePropertiesXML(ImageAsset image, + PageState state, + Element element) { - element.addAttribute("name_label", (String)GlobalizationUtil.globalize( - "cms.contentasset.image.ui.display.name") - .localize()); - element.addAttribute("name", image.getName()); - element.addAttribute("src", URL.getDispatcherPath() + - Service.getImageURL(image)); + element.addAttribute("name_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.display.name") + .localize()); + element.addAttribute("name", image.getName()); + element.addAttribute("src", URL.getDispatcherPath() + + Service.getImageURL(image)); - element.addAttribute("mime_type_label", (String)GlobalizationUtil.globalize( - "cms.contentasset.image.ui.display.type") - .localize()); - MimeType mimeType = image.getMimeType(); - if ( mimeType != null ) { - element.addAttribute("mime_type", mimeType.getLabel()); - } + element.addAttribute("mime_type_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.display.type") + .localize()); + MimeType mimeType = image.getMimeType(); + if (mimeType != null) { + element.addAttribute("mime_type", mimeType.getLabel()); + } - element.addAttribute("width_label", (String)GlobalizationUtil.globalize( - "cms.contentasset.image.ui.display.width") - .localize()); - BigDecimal width = image.getWidth(); - if ( width != null ) { - element.addAttribute("width", width.toString()); - } else { - element.addAttribute("width", (String)GlobalizationUtil.globalize( - "cms.ui.unknown") - .localize()); - } + element.addAttribute("width_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.display.width") + .localize()); + BigDecimal width = image.getWidth(); + if (width != null) { + element.addAttribute("width", width.toString()); + } else { + element.addAttribute("width", (String) GlobalizationUtil.globalize( + "cms.ui.unknown") + .localize()); + } - element.addAttribute("height_label", (String)GlobalizationUtil.globalize( - "cms.contentasset.image.ui.display.height") - .localize()); - BigDecimal height = image.getHeight(); - if ( height != null ) { - element.addAttribute("height", height.toString()); - } else { - element.addAttribute("height", (String)GlobalizationUtil.globalize( - "cms.ui.unknown") - .localize()); - } - } + element.addAttribute("height_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.display.height") + .localize()); + BigDecimal height = image.getHeight(); + if (height != null) { + element.addAttribute("height", height.toString()); + } else { + element.addAttribute("height", (String) GlobalizationUtil.globalize( + "cms.ui.unknown") + .localize()); + } - /** - * - * @param state - * @return - */ - protected ImageAsset getImageAsset(PageState state) { - ImageAsset image = (ImageAsset) m_item.getSelectedObject(state); - Assert.exists(image, "Image asset"); - return image; - } + element.addAttribute("dimension_label", (String) GlobalizationUtil.globalize( + "cms.contentasset.image.ui.display.dimensions") + .localize()); + } + + /** + * + * @param state + * @return + */ + protected ImageAsset getImageAsset(PageState state) { + ImageAsset image = (ImageAsset) m_item.getSelectedObject(state); + Assert.exists(image, "Image asset"); + return image; + } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageLibraryComponent.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageLibraryComponent.java index 47862f9db..089861a54 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageLibraryComponent.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageLibraryComponent.java @@ -34,7 +34,7 @@ import java.math.BigDecimal; * extended from {@link ImageComponentAbstractListener}. * * @author unknown - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageLibraryComponent extends SimpleContainer implements ImageComponent, Resettable { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java index 94acb0753..a0fcbe39d 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectPage.java @@ -22,149 +22,149 @@ import org.apache.log4j.Logger; /** * A {@link CMSPage} to select and upload images. - * - * This page is used by /web/templates/ccm-cms/content-section/admin/image_select.jsp - * which is used by the OpenCCM plugin for Xihna editor. - * - * @author Sören Bernstein (quasimodo) + * + * This page is used by + * /web/templates/ccm-cms/content-section/admin/image_select.jsp which is used + * by the OpenCCM plugin for Xinha editor. + * + * @author Sören Bernstein */ public class ImageSelectPage extends CMSPage { - private static final Logger S_LOG = Logger.getLogger(ImagesPane.class); - - private final static String XSL_CLASS = "CMS Admin"; - private TabbedPane m_tabbedPane; - private ImageLibraryComponent m_imageLibrary; - private ImageUploadComponent m_imageUpload; - private ImageSelectResultComponent m_result; - private BigDecimalParameter m_sectionId; - private final StringParameter m_imageComponentKey; - private final MapComponentSelectionModel m_imageComponent; - private final ImageComponentSelectListener m_selectListener; - private static final CMSConfig s_conf = CMSConfig.getInstance(); - public static final String CONTENT_SECTION = "section_id"; - public static final String RESULT = "result"; + private static final Logger S_LOG = Logger.getLogger(ImagesPane.class); + private final static String XSL_CLASS = "CMS Admin"; + private TabbedPane m_tabbedPane; + private ImageLibraryComponent m_imageLibrary; + private ImageUploadComponent m_imageUpload; + private ImageSelectResultComponent m_result; + private BigDecimalParameter m_sectionId; + private final StringParameter m_imageComponentKey; + private final MapComponentSelectionModel m_imageComponent; + private final ImageComponentSelectListener m_selectListener; + private static final CMSConfig s_conf = CMSConfig.getInstance(); + public static final String CONTENT_SECTION = "section_id"; + public static final String RESULT = "result"; - public ImageSelectPage() { - super(GlobalizationUtil.globalize( - "cms.ui.image_select.page_title") - .localize().toString(), - new SimpleContainer()); + public ImageSelectPage() { + super(GlobalizationUtil.globalize( + "cms.ui.image_select.page_title") + .localize().toString(), + new SimpleContainer()); - setClassAttr("cms-admin"); + setClassAttr("cms-admin"); - m_sectionId = new BigDecimalParameter(CONTENT_SECTION); - addGlobalStateParam(m_sectionId); + m_sectionId = new BigDecimalParameter(CONTENT_SECTION); + addGlobalStateParam(m_sectionId); - m_imageComponentKey = new StringParameter("imageComponent"); + m_imageComponentKey = new StringParameter("imageComponent"); - ParameterSingleSelectionModel componentModel = - new ParameterSingleSelectionModel(m_imageComponentKey); - m_imageComponent = - new MapComponentSelectionModel(componentModel, new HashMap()); - - m_selectListener = new ImageComponentSelectListener(m_imageComponent, - getResultComponent()); + ParameterSingleSelectionModel componentModel = + new ParameterSingleSelectionModel(m_imageComponentKey); + m_imageComponent = + new MapComponentSelectionModel(componentModel, new HashMap()); - m_tabbedPane = createTabbedPane(); - m_tabbedPane.setIdAttr("page-body"); + m_selectListener = new ImageComponentSelectListener(m_imageComponent, + getResultComponent()); - add(m_tabbedPane); - // ActionListener to change the image component state param to the - // right value - addActionListener(new ActionListener() { + m_tabbedPane = createTabbedPane(); + m_tabbedPane.setIdAttr("page-body"); - public void actionPerformed(ActionEvent event) { - final PageState ps = event.getPageState(); + add(m_tabbedPane); + // ActionListener to change the image component state param to the + // right value + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent event) { + final PageState ps = event.getPageState(); - if (m_tabbedPane.getCurrentPane(ps).equals(m_imageLibrary)) { - m_imageComponent.setSelectedKey(ps, ImageComponent.LIBRARY); - } - if (m_tabbedPane.getCurrentPane(ps).equals(m_imageUpload)) { - m_imageComponent.setSelectedKey(ps, ImageComponent.UPLOAD); - } - } - }); - - add(m_result); - - addGlobalStateParam(m_imageComponentKey); - } + if (m_tabbedPane.getCurrentPane(ps).equals(m_imageLibrary)) { + m_imageComponent.setSelectedKey(ps, ImageComponent.LIBRARY); + } + if (m_tabbedPane.getCurrentPane(ps).equals(m_imageUpload)) { + m_imageComponent.setSelectedKey(ps, ImageComponent.UPLOAD); + } + } + }); - /** - * Create the image library pane - * - * @return m_imageLibrary - */ - protected ImageLibraryComponent getImageLibraryPane() { - if (m_imageLibrary == null) { - m_imageLibrary = new ImageLibraryComponent(ImageComponent.SELECT_IMAGE, - this); - m_imageLibrary.getForm().addInitListener(m_selectListener); - m_imageLibrary.getForm().addProcessListener(m_selectListener); - m_imageComponent.getComponentsMap().put(ImageComponent.LIBRARY, - m_imageLibrary); - } - return m_imageLibrary; - } + add(m_result); - /** - * Create the image upload pane - * - * @return m_imageUpload - */ - protected ImageUploadComponent getImageUploadPane() { + addGlobalStateParam(m_imageComponentKey); + } - if (m_imageUpload == null) { - m_imageUpload = new ImageUploadComponent(ImageComponent.SELECT_IMAGE); - m_imageUpload.getForm().addInitListener(m_selectListener); - m_imageUpload.getForm().addProcessListener(m_selectListener); - m_imageComponent.getComponentsMap().put(ImageComponent.UPLOAD, - m_imageUpload); - } - return m_imageUpload; - } + /** + * Create the image library pane + * + * @return m_imageLibrary + */ + protected ImageLibraryComponent getImageLibraryPane() { + if (m_imageLibrary == null) { + m_imageLibrary = new ImageLibraryComponent(ImageComponent.SELECT_IMAGE, + this); + m_imageLibrary.getForm().addInitListener(m_selectListener); + m_imageLibrary.getForm().addProcessListener(m_selectListener); + m_imageComponent.getComponentsMap().put(ImageComponent.LIBRARY, + m_imageLibrary); + } + return m_imageLibrary; + } - /** - * Creates an {@link ImageSelectResultComponent} - * - * @return m_resultPane - */ - protected ImageSelectResultComponent getResultComponent() { - if (m_result == null) { - m_result = new ImageSelectResultComponent(); - } - return m_result; - } + /** + * Create the image upload pane + * + * @return m_imageUpload + */ + protected ImageUploadComponent getImageUploadPane() { - /** - * Create the tabbed pane - */ - protected TabbedPane createTabbedPane() { - TabbedPane pane = new TabbedPane(); - pane.setClassAttr(XSL_CLASS); + if (m_imageUpload == null) { + m_imageUpload = new ImageUploadComponent(ImageComponent.SELECT_IMAGE); + m_imageUpload.getForm().addInitListener(m_selectListener); + m_imageUpload.getForm().addProcessListener(m_selectListener); + m_imageComponent.getComponentsMap().put(ImageComponent.UPLOAD, + m_imageUpload); + } + return m_imageUpload; + } - addToPane(pane, ImageComponent.LIBRARY, getImageLibraryPane()); - addToPane(pane, ImageComponent.UPLOAD, getImageUploadPane()); - pane.setDefaultPane(m_imageLibrary); + /** + * Creates an {@link ImageSelectResultComponent} + * + * @return m_resultPane + */ + protected ImageSelectResultComponent getResultComponent() { + if (m_result == null) { + m_result = new ImageSelectResultComponent(); + } + return m_result; + } - return pane; - } + /** + * Create the tabbed pane + */ + protected TabbedPane createTabbedPane() { + TabbedPane pane = new TabbedPane(); + pane.setClassAttr(XSL_CLASS); - /** - * Adds the specified component, with the specified tab name, to the tabbed - * pane only if it is not null. - * - * @param pane The pane to which to add the tab - * @param tabName The name of the tab if it's added - * @param comp The component to add to the pane - */ - protected void addToPane(final TabbedPane pane, - final String tabName, - final Component comp) { - if (comp != null) { - pane.addTab(GlobalizationUtil.globalize("cms.ui.image_" + tabName) - .localize().toString(), comp); - } - } + addToPane(pane, ImageComponent.LIBRARY, getImageLibraryPane()); + addToPane(pane, ImageComponent.UPLOAD, getImageUploadPane()); + pane.setDefaultPane(m_imageLibrary); + + return pane; + } + + /** + * Adds the specified component, with the specified tab name, to the + * tabbed pane only if it is not null. + * + * @param pane The pane to which to add the tab + * @param tabName The name of the tab if it's added + * @param comp The component to add to the pane + */ + protected void addToPane(final TabbedPane pane, + final String tabName, + final Component comp) { + if (comp != null) { + pane.addTab(GlobalizationUtil.globalize("cms.ui.image_" + tabName) + .localize().toString(), comp); + } + } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectResultComponent.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectResultComponent.java index 3807e5ecb..4ae299a45 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectResultComponent.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageSelectResultComponent.java @@ -16,91 +16,99 @@ import com.arsdigita.xml.Element; * A component which will insert a javascript to the xml output with the image * information for the OpenCCM plugin for Xinha editor. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageSelectResultComponent extends SimpleContainer - implements Resettable { + implements Resettable { - boolean m_valid = false; - ImageAsset m_image; - String m_lastImageComponent; + boolean m_valid = false; + ImageAsset m_image; + String m_lastImageComponent; - public ImageSelectResultComponent() { - super(); - } + public ImageSelectResultComponent() { + super(); + } - /** - * Save image imformation - * - * @param image an {@link ImageAsset} - */ - public void setResult(final ImageAsset image, final String lastComponent) { - m_image = image; - m_lastImageComponent = lastComponent; - m_valid = (m_image != null); - } + /** + * Save image imformation + * + * @param image an {@link ImageAsset} + */ + public void setResult(final ImageAsset image, final String lastComponent) { + m_image = image; + m_lastImageComponent = lastComponent; + m_valid = (m_image != null); + } - @Override - public void generateXML(PageState state, Element parent) { + /** + * Insert a script tag to the xml output with a JavaScript function to + * send the image information back to the Xinha plugin. + * + * @param state The current {@link PageState} + * @param parent The parent {@link Element} + */ + @Override + public void generateXML(PageState state, Element parent) { - Element scriptElem = parent.newChildElement("script"); - scriptElem.addAttribute("type", "text/javascript"); + Element scriptElem = parent.newChildElement("script"); + scriptElem.addAttribute("type", "text/javascript"); - StringBuilder script = new StringBuilder(1000); + StringBuilder script = new StringBuilder(1000); - // Create funtion - script.append("function selectImage(button) {"); + // Create function + script.append("function selectImage(button) {"); - // If there is a valid image - if (m_valid) { + // If there is a valid image + if (m_valid) { - // If in library mode, only listen to save button - if (m_lastImageComponent.equals(ImageComponent.LIBRARY)) { - script.append("if(button.id != \"save\" ) { return false; } "); - } + // If in library mode, only listen to save button + if (m_lastImageComponent.equals(ImageComponent.LIBRARY)) { + script.append("if(button.id != \"save\" ) { return false; } "); + } - // Send image parameters to xinha plugin - script.append("window.opener.openCCM.imageSet({"); - script.append(" src : \""); - script.append(URL.getDispatcherPath()); - script.append(Service.getImageURL(m_image)); - script.append("\", "); - script.append(" name : \""); - script.append(m_image.getDisplayName()); - script.append("\", "); - script.append(" width : \""); - script.append(m_image.getWidth()); - script.append("\", "); - script.append(" height : \""); - script.append(m_image.getHeight()); - script.append("\""); - script.append("});"); + // Send image parameters to xinha plugin + script.append("window.opener.openCCM.imageSet({"); + script.append(" src : \""); + script.append(URL.getDispatcherPath()); + script.append(Service.getImageURL(m_image)); + script.append("\", "); + script.append(" name : \""); + script.append(m_image.getDisplayName()); + script.append("\", "); + script.append(" width : \""); + script.append(m_image.getWidth()); + script.append("\", "); + script.append(" height : \""); + script.append(m_image.getHeight()); + script.append("\""); + script.append("});"); - // Close window - script.append("self.close();"); + // Close window + script.append("self.close();"); - } - script.append("return false;"); - script.append("}"); + } + script.append("return false;"); + script.append("}"); - // If in upload mode and if there is a valid image, execute the - // javascript function - if (m_valid && ImageComponent.UPLOAD.equals(m_lastImageComponent)) { - script.append("selectImage();"); - } + // If in upload mode and if there is a valid image, execute the + // javascript function + if (m_valid && ImageComponent.UPLOAD.equals(m_lastImageComponent)) { + script.append("selectImage();"); + } - scriptElem.setText(script.toString()); + scriptElem.setText(script.toString()); - // Reset ImageSelectResultComponent - reset(state); - } + // Reset ImageSelectResultComponent + reset(state); + } - /** - * Reset this component. - * - * @param state Page state - */ - public void reset(PageState state) { - setResult(null, null); - } + /** + * Reset this component. + * + * @param state Page state + */ + @Override + public void reset(PageState state) { + setResult(null, null); + } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImageUploadComponent.java b/ccm-cms/src/com/arsdigita/cms/ui/ImageUploadComponent.java index 1539d580a..a7979944d 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImageUploadComponent.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImageUploadComponent.java @@ -25,64 +25,64 @@ import java.io.IOException; /** * An image upload component. * - * This component can be used in different places to add image upload capabilities - * in a convinient way. This class uses a listener class which should be extended - * from {@link ImageComponentAbstractListener}. - * + * This component can be used in different places to add image upload + * capabilities in a convinient way. This class uses a listener class which + * should be extended from {@link ImageComponentAbstractListener}. + * * @author unknown - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImageUploadComponent extends Form implements ImageComponent { - private final FileUploadSection m_imageFile; - private final TextField m_caption; - private final TextField m_title; - private final TextArea m_description; - private final TextField m_useContext; - private final SaveCancelSection m_saveCancel; - private int m_mode; + private final FileUploadSection m_imageFile; + private final TextField m_caption; + private final TextField m_title; + private final TextArea m_description; + private final TextField m_useContext; + private final SaveCancelSection m_saveCancel; + private int m_mode; - /** - * Creates an ImageUploadComponent in attach mode. - */ - public ImageUploadComponent() { - this(ImageComponent.ATTACH_IMAGE); - } + /** + * Creates an ImageUploadComponent in attach mode. + */ + public ImageUploadComponent() { + this(ImageComponent.ATTACH_IMAGE); + } - /** - * Creates an ImageUploadComponent with the selected mode. - * - * @param mode The operation mode (see {@link ImageComponent) - */ - public ImageUploadComponent(int mode) { - super("imageUploadComponent", new ColumnPanel(2)); - m_mode = mode; - setEncType("multipart/form-data"); - m_imageFile = new FileUploadSection(GlobalizationUtil.globalize( - "cms.contentasset.image.ui.type"), - "image", - ImageAsset.MIME_JPEG); - m_imageFile.getFileUploadWidget() - .addValidationListener(new NotNullValidationListener()); - add(m_imageFile, ColumnPanel.FULL_WIDTH); + /** + * Creates an ImageUploadComponent with the selected mode. + * + * @param mode The operation mode (see {@link ImageComponent) + */ + public ImageUploadComponent(int mode) { + super("imageUploadComponent", new ColumnPanel(2)); + m_mode = mode; + setEncType("multipart/form-data"); + m_imageFile = new FileUploadSection(GlobalizationUtil.globalize( + "cms.contentasset.image.ui.type"), + "image", + ImageAsset.MIME_JPEG); + m_imageFile.getFileUploadWidget() + .addValidationListener(new NotNullValidationListener()); + add(m_imageFile, ColumnPanel.FULL_WIDTH); - // Initialize all widgets - m_caption = new TextField("caption"); - m_title = new TextField("title"); - m_description = new TextArea("description"); - m_useContext = new TextField("useContext"); + // Initialize all widgets + m_caption = new TextField("caption"); + m_title = new TextField("title"); + m_description = new TextArea("description"); + m_useContext = new TextField("useContext"); - // add widget only if we are in attach mode - if (m_mode == ImageComponent.ATTACH_IMAGE) { - add(new Label(GlobalizationUtil - .globalize("cms.contentasset.image.ui.caption"))); - m_caption.addValidationListener(new NotNullValidationListener()); - m_caption.addValidationListener(new StringLengthValidationListener(40)); - m_caption.setSize(40); - add(m_caption); + // add widget only if we are in attach mode + if (m_mode == ImageComponent.ATTACH_IMAGE) { + add(new Label(GlobalizationUtil + .globalize("cms.contentasset.image.ui.caption"))); + m_caption.addValidationListener(new NotNullValidationListener()); + m_caption.addValidationListener(new StringLengthValidationListener(40)); + m_caption.setSize(40); + add(m_caption); - // We only show the title and description fields in the case where - // getIsImageStepDescriptionAndTitleShown is false. + // We only show the title and description fields in the case where + // getIsImageStepDescriptionAndTitleShown is false. // if (ItemImageAttachment.getConfig().getIsImageStepDescriptionAndTitleShown()) { // add(new Label("Title")); @@ -100,68 +100,78 @@ public class ImageUploadComponent extends Form implements ImageComponent { // // } - add(new Label(GlobalizationUtil - .globalize("cms.contentasset.image.ui.use_context"))); - m_useContext.setSize(40); - add(m_useContext); - } - m_saveCancel = new SaveCancelSection(); - add(m_saveCancel); + add(new Label(GlobalizationUtil + .globalize("cms.contentasset.image.ui.use_context"))); + m_useContext.setSize(40); + add(m_useContext); + } + m_saveCancel = new SaveCancelSection(); + add(m_saveCancel); - /* - * Removed by Quasimodo: Changed editing workflow, so that library comes - * first Also, library mode has now a link to upload images which will - * link to this form. Consequently, this link will create a loop, which - * isn't fatal but confusing. ActionLink library = new ActionLink( - * "Select an existing image" ); library.addActionListener( new - * ActionListener() { public void actionPerformed( ActionEvent ev ) { - * setImageComponent( ev.getPageState(), LIBRARY ); } } ); add( library, - * ColumnPanel.FULL_WIDTH ); - */ - } + /* + * Removed by Quasimodo: Changed editing workflow, so that library comes + * first Also, library mode has now a link to upload images which will + * link to this form. Consequently, this link will create a loop, which + * isn't fatal but confusing. + * + * ActionLink library = new ActionLink("Select an existing image" ); + * library.addActionListener( new ActionListener() { + * public void actionPerformed( ActionEvent ev ) { + * setImageComponent( ev.getPageState(), LIBRARY ); + * } + * } ); + * add( library, ColumnPanel.FULL_WIDTH ); + */ + } - public SaveCancelSection getSaveCancelSection() { - return m_saveCancel; - } + @Override + public SaveCancelSection getSaveCancelSection() { + return m_saveCancel; + } - public ReusableImageAsset getImage(FormSectionEvent event) - throws FormProcessException { - PageState ps = event.getPageState(); - String filename = (String) m_imageFile.getFileName(event); - File imageFile = m_imageFile.getFile(event); - try { - ReusableImageAsset image = new ReusableImageAsset(); - image.loadFromFile(filename, imageFile, ImageAsset.MIME_JPEG); + @Override + public ReusableImageAsset getImage(FormSectionEvent event) + throws FormProcessException { + PageState ps = event.getPageState(); + String filename = (String) m_imageFile.getFileName(event); + File imageFile = m_imageFile.getFile(event); + try { + ReusableImageAsset image = new ReusableImageAsset(); + image.loadFromFile(filename, imageFile, ImageAsset.MIME_JPEG); // image.setDescription((String) m_caption.getValue(ps)); - return image; - } catch (IOException ex) { - ImagesPane.S_LOG.error("Error loading image from file", ex); - throw new FormProcessException(ex.getMessage()); - } - } + return image; + } catch (IOException ex) { + ImagesPane.S_LOG.error("Error loading image from file", ex); + throw new FormProcessException(ex.getMessage()); + } + } - public String getCaption(FormSectionEvent event) { - PageState ps = event.getPageState(); - return (String) m_caption.getValue(ps); - } + @Override + public String getCaption(FormSectionEvent event) { + PageState ps = event.getPageState(); + return (String) m_caption.getValue(ps); + } - public String getDescription(FormSectionEvent event) { - PageState ps = event.getPageState(); - return (String) m_description.getValue(ps); - } + @Override + public String getDescription(FormSectionEvent event) { + PageState ps = event.getPageState(); + return (String) m_description.getValue(ps); + } - public String getTitle(FormSectionEvent event) { - PageState ps = event.getPageState(); - return (String) m_title.getValue(ps); - } + @Override + public String getTitle(FormSectionEvent event) { + PageState ps = event.getPageState(); + return (String) m_title.getValue(ps); + } - public String getUseContext(FormSectionEvent event) { - PageState ps = event.getPageState(); - return (String) m_useContext.getValue(ps); - } - - public Form getForm() { - return this; - } + @Override + public String getUseContext(FormSectionEvent event) { + PageState ps = event.getPageState(); + return (String) m_useContext.getValue(ps); + } + @Override + public Form getForm() { + return this; + } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ImagesPane.java b/ccm-cms/src/com/arsdigita/cms/ui/ImagesPane.java index ffd329ca8..897899eb4 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ImagesPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ImagesPane.java @@ -37,7 +37,7 @@ import org.apache.log4j.Logger; /** * A {@link LayoutPanel} to insert into {@link ContentSectionPage}. * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class ImagesPane extends LayoutPanel implements Resettable { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java index e047a8284..11b58b5cc 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchCreateItemPane.java @@ -53,7 +53,7 @@ import java.math.BigDecimal; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * @author Jens Pelzetter */ class ItemSearchCreateItemPane extends CMSContainer diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java index 70f43bc3e..1c65d789d 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemSearchPage.java @@ -51,7 +51,7 @@ import javax.servlet.http.HttpServletResponse; *

The Item Search page.

* * @author Scott Seago (scott@arsdigita.com) - * @author Sören Bernstein (sbernstein@quasiweb.de) + * @author Sören Bernstein * @author Jens Pelzetter (jens@jp-digital.de) */ public class ItemSearchPage extends CMSPage { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java index 99a0a8ce6..90fb290e4 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryItemPane.java @@ -75,7 +75,7 @@ import org.apache.log4j.Logger; * Edits a single category. * * @author Justin Ross <jross@redhat.com> - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein * @version $Id: CategoryItemPane.java 1967 2009-08-29 21:05:51Z pboy $ */ class CategoryItemPane extends BaseItemPane { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java index 92d2fb788..21199feff 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationAddForm.java @@ -41,7 +41,7 @@ import org.apache.log4j.Logger; * This class is part of the admin GUI of CCM and extends the standard form * in order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein * @version $Id: CategoryLocalizationAddForm.java 287 2005-02-22 00:29:02Z sskracic $ */ public class CategoryLocalizationAddForm extends CategoryLocalizationForm { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java index df423ad6f..08114e879 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationEditForm.java @@ -37,7 +37,7 @@ import org.apache.log4j.Logger; * This class is part of the admin GUI of CCM and extends the standard form * in order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein * @version $Id: CategoryLocalizationEditForm.java $ */ public class CategoryLocalizationEditForm extends CategoryLocalizationForm { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java index 94b6292ca..650e3cf11 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationForm.java @@ -48,7 +48,7 @@ import com.arsdigita.xml.Element; * This class is part of the admin GUI of CCM and extends the standard form * in order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein * @version $Id: $ */ public class CategoryLocalizationForm extends BaseForm { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java index c1b020973..5f37527c0 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/category/CategoryLocalizationTable.java @@ -45,7 +45,7 @@ import java.util.Locale; * This class is part of the admin GUI of CCM and extends the standard form in * order to present forms for managing the multi-language categories. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein */ public class CategoryLocalizationTable extends Table implements TableActionListener { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/folder/AbstractFolderPicker.java b/ccm-cms/src/com/arsdigita/cms/ui/folder/AbstractFolderPicker.java index e38768839..58ff0807f 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/folder/AbstractFolderPicker.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/folder/AbstractFolderPicker.java @@ -16,7 +16,7 @@ import java.util.TooManyListenersException; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public abstract class AbstractFolderPicker extends SingleSelect { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/folder/FlatFolderPicker.java b/ccm-cms/src/com/arsdigita/cms/ui/folder/FlatFolderPicker.java index 201ed6413..10a327323 100644 --- a/ccm-cms/src/com/arsdigita/cms/ui/folder/FlatFolderPicker.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/folder/FlatFolderPicker.java @@ -14,7 +14,7 @@ import com.arsdigita.cms.ItemCollection; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein * @author Jens Pelzetter * @version $Id$ */ diff --git a/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderBrowser.java b/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderBrowser.java index 7987a3e89..19930c878 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderBrowser.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/folder/FolderBrowser.java @@ -70,7 +70,7 @@ import javax.servlet.ServletException; * item selection model is updated. * * @author David Lutterkort - * @author Sören Bernstein + * @author Sören Bernstein * @version $Id: FolderBrowser.java 2017 2009-10-04 09:03:45Z pboy $ */ public class FolderBrowser extends Table { @@ -509,7 +509,7 @@ public class FolderBrowser extends Table { } /** - * Added by: Sören Bernstein + * Added by: Sören Bernstein * * Produce links to view an item in a specific language and show all * existing language version and the live status in the folder browser. diff --git a/ccm-cms/src/com/arsdigita/cms/ui/role/BaseRoleForm.java b/ccm-cms/src/com/arsdigita/cms/ui/role/BaseRoleForm.java index 23874eb80..aa0453b4e 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/role/BaseRoleForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/role/BaseRoleForm.java @@ -82,6 +82,7 @@ public class BaseRoleForm extends BaseForm { } private class PrivilegePrinter implements PrintListener { + @Override public final void prepare(final PrintEvent e) { final CheckboxGroup target = (CheckboxGroup) e.getTarget(); final PageState state = e.getPageState(); @@ -107,6 +108,7 @@ public class BaseRoleForm extends BaseForm { m_role = role; } + @Override public final void validate(final ParameterEvent e) throws FormProcessException { final PageState state = e.getPageState(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/search/ItemQueryComponent.java b/ccm-cms/src/com/arsdigita/cms/ui/search/ItemQueryComponent.java index 1571c2f42..6cf565aaf 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/search/ItemQueryComponent.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/search/ItemQueryComponent.java @@ -48,7 +48,7 @@ import java.util.List; * search query engine. * * @author unknown - * @author Sören Bernstein (sbernstein@quasiweb.de) + * @author Sören Bernstein * @author Jens Pelzetter (jens@jp-digital.de) */ public class ItemQueryComponent extends BaseQueryComponent { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java index 38adbda73..a194e3063 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/workflow/AssignedTaskSection.java @@ -41,7 +41,7 @@ import org.apache.log4j.Logger; /** * @author unknown - * @author Sören Bernstein + * @author Sören Bernstein * @version $Id: AssignedTaskSection.java 1280 2006-07-27 09:12:09Z cgyg9330 $ */ public final class AssignedTaskSection extends Section { diff --git a/ccm-cms/src/com/arsdigita/cms/util/LanguageUtil.java b/ccm-cms/src/com/arsdigita/cms/util/LanguageUtil.java index 1b1bb3976..739372602 100755 --- a/ccm-cms/src/com/arsdigita/cms/util/LanguageUtil.java +++ b/ccm-cms/src/com/arsdigita/cms/util/LanguageUtil.java @@ -38,7 +38,7 @@ import java.util.StringTokenizer; * Utility methods for dealing with the multilingual items. * * @author Shashin Shinde (sshinde@redhat.com) - * @author Sören Bernstein + * @author Sören Bernstein */ public class LanguageUtil { diff --git a/ccm-core/src/com/arsdigita/bebop/Page.java b/ccm-core/src/com/arsdigita/bebop/Page.java index 40780144f..800900836 100755 --- a/ccm-core/src/com/arsdigita/bebop/Page.java +++ b/ccm-core/src/com/arsdigita/bebop/Page.java @@ -75,612 +75,624 @@ import org.apache.log4j.Logger; */ public class Page extends BlockStylable implements Container { - /** - * Class specific logger instance. - */ - private static final Logger s_log = Logger.getLogger(Page.class); - /** - * The delimiter character for components naming - */ - private static final String DELIMITER = "."; - /** - * The prefix that gets prepended to all state variables. Components must - * not use variables starting with this prefix. This guarantees that the - * page state and variables individual components wish to pass do not - * interfere with each other. - */ - private static final String COMPONENT_PREFIX = "bbp" + DELIMITER; - private static final String INTERNAL = COMPONENT_PREFIX; - /** - * The name of the special parameter that indicates which component has been - * selected. - */ - static final String SELECTED = INTERNAL + "s"; - static final String CONTROL_EVENT = INTERNAL + "e"; - static final String CONTROL_VALUE = INTERNAL + "v"; - static final Collection CONTROL_EVENT_KEYS; + /** + * Class specific logger instance. + */ + private static final Logger s_log = Logger.getLogger(Page.class); + /** + * The delimiter character for components naming + */ + private static final String DELIMITER = "."; + /** + * The prefix that gets prepended to all state variables. Components + * must not use variables starting with this prefix. This guarantees + * that the page state and variables individual components wish to pass + * do not interfere with each other. + */ + private static final String COMPONENT_PREFIX = "bbp" + DELIMITER; + private static final String INTERNAL = COMPONENT_PREFIX; + /** + * The name of the special parameter that indicates which component has + * been selected. + */ + static final String SELECTED = INTERNAL + "s"; + static final String CONTROL_EVENT = INTERNAL + "e"; + static final String CONTROL_VALUE = INTERNAL + "v"; + static final Collection CONTROL_EVENT_KEYS; - static { - s_log.debug("Static initalizer is starting..."); - CONTROL_EVENT_KEYS = new ArrayList(3); - CONTROL_EVENT_KEYS.add(SELECTED); - CONTROL_EVENT_KEYS.add(CONTROL_EVENT); - CONTROL_EVENT_KEYS.add(CONTROL_VALUE); - s_log.debug("Static initalizer finished."); - } - /** - * The name of the request parameter used for the visibility state of - * components stored in m_invisible. - */ - static final String INVISIBLE = INTERNAL + "i"; - /** - * Map of stateful components (id --> Component) SortedMap used because - * component based hash for page is based on concatenation of component ids, - * and so need to guarantee that they are returned in the same order for the - * same page - cg. - */ - private SortedMap m_componentMap; - private List m_components; - /** - * Map of component -> owned parameter collection - */ - private Map m_componentParameterMap = new HashMap(); - private FormModel m_stateModel; - /** - * Container that renders this - * Page. - */ - protected Container m_panel; - private List m_actionListeners; - private List m_requestListeners; - /** - * The title of the page to be added in the head of HTML output. The title - * is wrapped in a Label to allow developers to add PrintListeners to - * dynamically change the value of the title. - */ - private Label m_title; - /** - * Stores the actual title for the current request. The title may be - * generated with a PrintListener of the m_title Label. - */ - private RequestLocal m_currentTitle; - /** - * A list of all the client-side stylesheets. The elements of the list are - * of type Page.Stylesheet, defined at the end of this file. - */ - private List m_clientStylesheets; - private StringParameter m_selected; - private StringParameter m_controlEvent; - private StringParameter m_controlValue; - /** - * The default (initial) visibility of components. The encoding is identical - * to that for PageState.m_invisible. - * - * This variable is package-friendly since it needs to be accessed by - * PageState. - */ - protected BitSet m_invisible; - /** - * The PageErrorDisplay component that will display page state validation - * errors on this page - */ - private Component m_errorDisplay; - /** - * Indicates whether finish() has been called on this Page. - */ - private boolean m_finished = false; - /** - * indicates whether pageState.stateAsURL() should export the entire state - * for this page, or whether it should only export the control event as a - * URL and use the HttpSession for the rest of the page state. - */ - private boolean m_useHttpSession = false; - - /** - * Returns - * true if this page should export state through the - * HttpSession instead of the URL query string.

If this returns - * true, then PageState.stateAsURL() will only export the - * control event as a URL query string. If this returns - * false, then stateAsURL() will export the entire page state. - * - * - * @see PageState#stateAsURL - * - * @return true if this page should export state through the - * HttpSession; false if it should export using the URL query - * string. - */ - public boolean isUsingHttpSession() { - return m_useHttpSession; - } + static { + s_log.debug("Static initalizer is starting..."); + CONTROL_EVENT_KEYS = new ArrayList(3); + CONTROL_EVENT_KEYS.add(SELECTED); + CONTROL_EVENT_KEYS.add(CONTROL_EVENT); + CONTROL_EVENT_KEYS.add(CONTROL_VALUE); + s_log.debug("Static initalizer finished."); + } + /** + * The name of the request parameter used for the visibility state of + * components stored in m_invisible. + */ + static final String INVISIBLE = INTERNAL + "i"; + /** + * Map of stateful components (id --> Component) SortedMap used because + * component based hash for page is based on concatenation of component + * ids, and so need to guarantee that they are returned in the same + * order for the same page - cg. + */ + private SortedMap m_componentMap; + private List m_components; + /** + * Map of component -> owned parameter collection + */ + private Map m_componentParameterMap = new HashMap(); + private FormModel m_stateModel; + /** + * Container that renders this + * Page. + */ + protected Container m_panel; + private List m_actionListeners; + private List m_requestListeners; + /** + * The title of the page to be added in the head of HTML output. The + * title is wrapped in a Label to allow developers to add PrintListeners + * to dynamically change the value of the title. + */ + private Label m_title; + /** + * Stores the actual title for the current request. The title may be + * generated with a PrintListener of the m_title Label. + */ + private RequestLocal m_currentTitle; + /** + * A list of all the client-side stylesheets. The elements of the list + * are of type Page.Stylesheet, defined at the end of this file. + */ + private List m_clientStylesheets; + private StringParameter m_selected; + private StringParameter m_controlEvent; + private StringParameter m_controlValue; + /** + * The default (initial) visibility of components. The encoding is + * identical to that for PageState.m_invisible. + * + * This variable is package-friendly since it needs to be accessed by + * PageState. + */ + protected BitSet m_invisible; + /** + * The PageErrorDisplay component that will display page state + * validation errors on this page + */ + private Component m_errorDisplay; + /** + * Indicates whether finish() has been called on this Page. + */ + private boolean m_finished = false; + /** + * indicates whether pageState.stateAsURL() should export the entire + * state for this page, or whether it should only export the control + * event as a URL and use the HttpSession for the rest of the page + * state. + */ + private boolean m_useHttpSession = false; - /** - * Indicates to this page whether it should export its entire state to - * subsequent requests through the URL query string, or if it should use the - * HttpSession instead and only use the URL query string for the control - * event. - * - * @see PageState#stateAsURL - * - * @param b true if PageState.stateAsURL() will export only the - * control event as a URL query string. false if stateAsURL() - * will export the entire page state. - */ - public void setUsingHttpSession(boolean b) { - m_useHttpSession = b; - } + /** + * Returns + * true if this page should export state through the + * HttpSession instead of the URL query string.

If this returns + * true, then PageState.stateAsURL() will only export the + * control event as a URL query string. If this returns + * false, then stateAsURL() will export the entire page + * state. + * + * + * @see PageState#stateAsURL + * + * @return true if this page should export state through + * the HttpSession; false if it should export using the URL + * query string. + */ + public boolean isUsingHttpSession() { + return m_useHttpSession; + } - /** - * Creates an empty page with the specified title and panel. - * - * @param title title for this page - * - * @param panel container for this page - */ - public Page(String title, Container panel) { - this(new Label(title), panel); - } + /** + * Indicates to this page whether it should export its entire state to + * subsequent requests through the URL query string, or if it should use + * the HttpSession instead and only use the URL query string for the + * control event. + * + * @see PageState#stateAsURL + * + * @param b true if PageState.stateAsURL() will export only + * the control event as a URL query string. false if + * stateAsURL() will export the entire page state. + */ + public void setUsingHttpSession(boolean b) { + m_useHttpSession = b; + } - /** - * Creates an empty page with the specified title and panel. - * - * @param title title for this page - * - * @param panel container for this page - */ - public Page(Label title, Container panel) { - super(); - m_actionListeners = new LinkedList(); - m_requestListeners = new LinkedList(); - m_panel = panel; - m_clientStylesheets = new ArrayList(); - m_components = new ArrayList(); - m_componentMap = new TreeMap(); - setErrorDisplay(new PageErrorDisplay()); - setTitle(title); + /** + * Creates an empty page with the specified title and panel. + * + * @param title title for this page + * + * @param panel container for this page + */ + public Page(String title, Container panel) { + this(new Label(title), panel); + } - // Initialize the RequestLocal where the title for the current - // request will be kept - m_currentTitle = new RequestLocal() { - @Override - protected Object initialValue(PageState state) { - return m_title.firePrintEvent(state); - } - }; + /** + * Creates an empty page with the specified title and panel. + * + * @param title title for this page + * + * @param panel container for this page + */ + public Page(Label title, Container panel) { + super(); + m_actionListeners = new LinkedList(); + m_requestListeners = new LinkedList(); + m_panel = panel; + m_clientStylesheets = new ArrayList(); + m_components = new ArrayList(); + m_componentMap = new TreeMap(); + setErrorDisplay(new PageErrorDisplay()); + setTitle(title); - // Initialize the set of state parameters to hold - // the ones necessary for keeping track of the selected component and - // the name and value of a 'control event' - m_selected = new StringParameter(SELECTED); - m_controlEvent = new StringParameter(CONTROL_EVENT); - m_controlValue = new StringParameter(CONTROL_VALUE); + // Initialize the RequestLocal where the title for the current + // request will be kept + m_currentTitle = new RequestLocal() { + @Override + protected Object initialValue(PageState state) { + return m_title.firePrintEvent(state); + } + }; - m_stateModel = new FormModel("stateModel", true); - m_stateModel.addFormParam(m_selected); - m_stateModel.addFormParam(m_controlEvent); - m_stateModel.addFormParam(m_controlValue); + // Initialize the set of state parameters to hold + // the ones necessary for keeping track of the selected component and + // the name and value of a 'control event' + m_selected = new StringParameter(SELECTED); + m_controlEvent = new StringParameter(CONTROL_EVENT); + m_controlValue = new StringParameter(CONTROL_VALUE); - // Set up the visibility tracking parameters - m_invisible = new BitSet(32); - BitSetParameter p = new BitSetParameter(INVISIBLE, - BitSetParameter.ENCODE_DGAP); - m_stateModel.addFormParam(p); - } + m_stateModel = new FormModel("stateModel", true); + m_stateModel.addFormParam(m_selected); + m_stateModel.addFormParam(m_controlEvent); + m_stateModel.addFormParam(m_controlValue); - /** - * Creates an empty page with default title and implicit BoxPanel container. - */ - public Page() { - this(""); - } + // Set up the visibility tracking parameters + m_invisible = new BitSet(32); + BitSetParameter p = new BitSetParameter(INVISIBLE, + BitSetParameter.ENCODE_DGAP); + m_stateModel.addFormParam(p); + } - /** - * Creates an empty page with the specified title and implicit BoxPanel - * container. - * - * @param title title for this page - */ - public Page(Label title) { - this(title, new BoxPanel()); - BoxPanel bp = (BoxPanel) m_panel; - bp.setWidth("100%"); - } + /** + * Creates an empty page with default title and implicit BoxPanel + * container. + */ + public Page() { + this(""); + } - /** - * Creates an empty page with the specified title and implicit BoxPanel - * container. - * - * @param title title for this page - */ - public Page(String title) { - this(new Label(title)); - } + /** + * Creates an empty page with the specified title and implicit BoxPanel + * container. + * + * @param title title for this page + */ + public Page(Label title) { + this(title, new BoxPanel()); + BoxPanel bp = (BoxPanel) m_panel; + bp.setWidth("100%"); + } - /** - * Adds a component to this container. - * - * @param c component to add to this container - */ - public void add(Component c) { - m_panel.add(c); + /** + * Creates an empty page with the specified title and implicit BoxPanel + * container. + * + * @param title title for this page + */ + public Page(String title) { + this(new Label(title)); + } - } + /** + * Adds a component to this container. + * + * @param c component to add to this container + */ + @Override + public void add(Component c) { + m_panel.add(c); - /** - * Adds a component with the specified layout constraints to this container. - * Layout constraints are defined in each layout container as static ints. - * To specify multiple constraints, use bitwise OR. - * - * @param c component to add to this container - * - * @param constraints layout constraints (a bitwise OR of static ints in the - * particular layout) - */ - public void add(Component c, int constraints) { - m_panel.add(c, constraints); - } + } - /** - * Returns - * true if this list contains the specified element. More - * formally, returns - * true if and only if this list contains at least one element - * e such that (o==null ? e==null : o.equals(e)).

This method returns - * true only if the component has been directly added to this - * container. If this container contains another container that contains - * this component, this method returns - * false. - * - * @param o element whose presence in this container is to be tested - * - * @return true if this Container contains the specified - * component directly; false otherwise. - */ - public boolean contains(Object o) { - return m_panel.contains(o); - } + /** + * Adds a component with the specified layout constraints to this + * container. Layout constraints are defined in each layout container as + * static ints. To specify multiple constraints, use bitwise OR. + * + * @param c component to add to this container + * + * @param constraints layout constraints (a bitwise OR of static ints in + * the particular layout) + */ + @Override + public void add(Component c, int constraints) { + m_panel.add(c, constraints); + } - /** - * Returns the component at the specified position. Each call to the add - * method increments the index. Since the user has no control over the index - * of added components (other than counting each call to add), this method - * should be used in conjunction with indexOf. - * - * @param index the index of the item to be retrieved from this Container - * - * @return the component at the specified position in this container. - */ - public Component get(int index) { - return m_panel.get(index); - } + /** + * Returns + * true if this list contains the specified element. More + * formally, returns + * true if and only if this list contains at least one + * element e such that (o==null ? e==null : o.equals(e)).

This + * method returns + * true only if the component has been directly added to + * this container. If this container contains another container that + * contains this component, this method returns + * false. + * + * @param o element whose presence in this container is to be tested + * + * @return true if this Container contains the specified + * component directly; false otherwise. + */ + @Override + public boolean contains(Object o) { + return m_panel.contains(o); + } - /** - * Gets the index of a component. - * - * @param c component to search for - * - * @return the index in this list of the first occurrence of the specified - * element, or -1 if this list does not contain this element. - * - * @pre c != null - * @post contains(c) implies (return >= 0) && (return < size()) - * @post !contains(c) implies return == -1 - */ - public int indexOf(Component c) { - return m_panel.indexOf(c); - } + /** + * Returns the component at the specified position. Each call to the add + * method increments the index. Since the user has no control over the + * index of added components (other than counting each call to add), + * this method should be used in conjunction with indexOf. + * + * @param index the index of the item to be retrieved from this + * Container + * + * @return the component at the specified position in this container. + */ + @Override + public Component get(int index) { + return m_panel.get(index); + } - /** - * Returns - * true if the container contains no components. - * - * @return true if this container contains no * * - * components; false otherwise. - */ - public boolean isEmpty() { - return m_panel.isEmpty(); - } + /** + * Gets the index of a component. + * + * @param c component to search for + * + * @return the index in this list of the first occurrence of the + * specified element, or -1 if this list does not contain this element. + * + * @pre c != null + * @post contains(c) implies (return >= 0) && (return < size()) + * @post !contains(c) implies return == -1 + */ + @Override + public int indexOf(Component c) { + return m_panel.indexOf(c); + } - /** - * Returns the number of elements in this container. This does not - * recursively count the components that are indirectly contained in this - * container. - * - * @return the number of components directly in this container. - */ - public int size() { - return m_panel.size(); - } + /** + * Returns + * true if the container contains no components. + * + * @return true if this container contains no * * + * components; false otherwise. + */ + @Override + public boolean isEmpty() { + return m_panel.isEmpty(); + } - @Override - public Iterator children() { - return Collections.singletonList(m_panel).iterator(); - } + /** + * Returns the number of elements in this container. This does not + * recursively count the components that are indirectly contained in + * this container. + * + * @return the number of components directly in this container. + */ + @Override + public int size() { + return m_panel.size(); + } - /** - * Returns the panel that the - * Page uses for rendering its components. - * - * @return the panel. - */ - public final Container getPanel() { - return m_panel; - } + @Override + public Iterator children() { + return Collections.singletonList(m_panel).iterator(); + } - /** - * Set the Container used for rendering components on this page. Caution - * should be used with this function, as the existing container is simply - * overwritten. - * - * @author Matthew Booth (mbooth@redhat.com) - */ - public void setPanel(Container c) { - m_panel = c; - } + /** + * Returns the panel that the + * Page uses for rendering its components. + * + * @return the panel. + */ + public final Container getPanel() { + return m_panel; + } - /** - *

Retrieves the title of this page.

- * - * @return the static title of this page. - */ - public final Label getTitle() { - return m_title; - } + /** + * Set the Container used for rendering components on this page. Caution + * should be used with this function, as the existing container is + * simply overwritten. + * + * @author Matthew Booth (mbooth@redhat.com) + */ + public void setPanel(Container c) { + m_panel = c; + } - /** - * Retrieves the title of this page as a Bebop label component. - * - * @param state the state of the current request - * @return the title of the page for the current request. - */ - public final Label getTitle(PageState state) { - return (Label) m_currentTitle.get(state); - } + /** + *

Retrieves the title of this page.

+ * + * @return the static title of this page. + */ + public final Label getTitle() { + return m_title; + } - /** - * Sets the title for this page from the passed in string. - * - * @param title title for this page - */ - public void setTitle(String title) { - Assert.isUnlocked(this); - setTitle(new Label(title)); - } + /** + * Retrieves the title of this page as a Bebop label component. + * + * @param state the state of the current request + * @return the title of the page for the current request. + */ + public final Label getTitle(PageState state) { + return (Label) m_currentTitle.get(state); + } - /** - * Set the title for this page from the passed in label. - * - * @param title title for this page - */ - public void setTitle(Label title) { - Assert.isUnlocked(this); - m_title = title; - } + /** + * Sets the title for this page from the passed in string. + * + * @param title title for this page + */ + public void setTitle(String title) { + Assert.isUnlocked(this); + setTitle(new Label(title)); + } - /** - * Sets the {@link Component} that will display the validation errors in the - * current {@link PageState}. Any validation error in the - * PageState will cause the - * Page to completely ignore all other components and render - * only the error display component.

By default, a - * {@link PageErrorDisplay} component is used to display the validation - * errors. - * - * @param c the component that will display the validation errors in the - * current PageState - */ - public final void setErrorDisplay(Component c) { - Assert.isUnlocked(this); - m_errorDisplay = c; - } + /** + * Set the title for this page from the passed in label. + * + * @param title title for this page + */ + public void setTitle(Label title) { + Assert.isUnlocked(this); + m_title = title; + } - /** - * Gets the {@link Component} that will display the validation errors in the - * current {@link PageState}. Any validation error in the - * PageState will cause the - * Page to completely ignore all other components and render - * only the error display component.

By default, a - * {@link PageErrorDisplay} component is used to display the validation - * errors. - * - * @return the component that will display the validation errors in the - * current PageState. - */ - public final Component getErrorDisplay() { - return m_errorDisplay; - } + /** + * Sets the {@link Component} that will display the validation errors in + * the current {@link PageState}. Any validation error in the + * PageState will cause the + * Page to completely ignore all other components and + * render only the error display component.

By default, a + * {@link PageErrorDisplay} component is used to display the validation + * errors. + * + * @param c the component that will display the validation errors in the + * current PageState + */ + public final void setErrorDisplay(Component c) { + Assert.isUnlocked(this); + m_errorDisplay = c; + } - /** - * Adds a client-side stylesheet that should be used in HTML output. - * Arbitrarily many client-side stylesheets can be added with this method. - * To use a CSS stylesheet, call something like - * setStyleSheet("style.css", "text/css"). - * - *

These values will ultimately wind up in a <link> tag - * in the head of the HTML page. - * - *

Note that the stylesheet set with this call has nothing to do with - * the XSLT stylesheet (transformer) that is applied to the XML generated - * from this page! - * - * @param styleSheetURI the location of the stylesheet - * @param mimeType the MIME type of the stylesheet, usually - * text/css - * @pre ! isLocked() - */ - public void addClientStylesheet(String styleSheetURI, String mimeType) { - m_clientStylesheets.add(new Stylesheet(styleSheetURI, mimeType)); - } + /** + * Gets the {@link Component} that will display the validation errors in + * the current {@link PageState}. Any validation error in the + * PageState will cause the + * Page to completely ignore all other components and + * render only the error display component.

By default, a + * {@link PageErrorDisplay} component is used to display the validation + * errors. + * + * @return the component that will display the validation errors in the + * current PageState. + */ + public final Component getErrorDisplay() { + return m_errorDisplay; + } - /** - * Adds a global state parameter to this page. Global parameters are values - * that need to be preserved between requests, but that have no special - * connection to any of the components on the page. For a page that displays - * details about an item, a global parameter would be used to identify the - * item. - * - *

If the parameter was previously added as a component state parameter, - * its name is unmangled and stays unmangled. - * - * @param p the global parameter to add - * - * @see #addComponentStateParam - * - * @pre ! isLocked() - * @pre parameter != null - */ - public void addGlobalStateParam(ParameterModel p) { - Assert.isUnlocked(this); - p.setName(unmangle(p.getName())); - m_stateModel.addFormParam(p); - } + /** + * Adds a client-side stylesheet that should be used in HTML output. + * Arbitrarily many client-side stylesheets can be added with this + * method. To use a CSS stylesheet, call something like + * setStyleSheet("style.css", "text/css"). + * + *

These values will ultimately wind up in a <link> + * tag in the head of the HTML page. + * + *

Note that the stylesheet set with this call has nothing to do + * with the XSLT stylesheet (transformer) that is applied to the XML + * generated from this page! + * + * @param styleSheetURI the location of the stylesheet + * @param mimeType the MIME type of the stylesheet, usually + * text/css + * @pre ! isLocked() + */ + public void addClientStylesheet(String styleSheetURI, String mimeType) { + m_clientStylesheets.add(new Stylesheet(styleSheetURI, mimeType)); + } - /** - * Constructs the top nodes of the DOM or JDOM tree. Used by - * generateXML(PageState, Document) below.

Generates DOM fragment: - *

-     * <bebop:page>
-     *   <bebop:title> ... value set with setTitle ... </bebop:title>
-     *   <bebop:stylesheet href='styleSheetURI' type='mimeType'>
-     *   ... page content gnerated by children ...
-     * </bebop:page>
The content of the <title> element - * can be set by calling {@link #setTitle setTitle}. The - * <stylesheet> element will only be present if a stylesheet - * has been set with {@link - * #setStyleSheet setStyleSheet}. - * - * @param ps the page state for the current page - * @param parent the DOM node for the whole Document - * - * @pre isLocked() - */ - protected Element generateXMLHelper(PageState ps, Document parent) { - Assert.isLocked(this); + /** + * Adds a global state parameter to this page. Global parameters are + * values that need to be preserved between requests, but that have no + * special connection to any of the components on the page. For a page + * that displays details about an item, a global parameter would be used + * to identify the item. + * + *

If the parameter was previously added as a component state + * parameter, its name is unmangled and stays unmangled. + * + * @param p the global parameter to add + * + * @see #addComponentStateParam + * + * @pre ! isLocked() + * @pre parameter != null + */ + public void addGlobalStateParam(ParameterModel p) { + Assert.isUnlocked(this); + p.setName(unmangle(p.getName())); + m_stateModel.addFormParam(p); + } - Element page = parent.createRootElement("bebop:page", BEBOP_XML_NS); - exportAttributes(page); + /** + * Constructs the top nodes of the DOM or JDOM tree. Used by + * generateXML(PageState, Document) below.

Generates DOM fragment: + *

+	 * <bebop:page>
+	 *   <bebop:title> ... value set with setTitle ... </bebop:title>
+	 *   <bebop:stylesheet href='styleSheetURI' type='mimeType'>
+	 *   ... page content gnerated by children ...
+	 * </bebop:page>
The content of the <title> + * element can be set by calling {@link #setTitle setTitle}. The + * <stylesheet> element will only be present if a + * stylesheet has been set with {@link + * #setStyleSheet setStyleSheet}. + * + * @param ps the page state for the current page + * @param parent the DOM node for the whole Document + * + * @pre isLocked() + */ + protected Element generateXMLHelper(PageState ps, Document parent) { + Assert.isLocked(this); - /* Generator information */ - exportSystemInformation(page); + Element page = parent.createRootElement("bebop:page", BEBOP_XML_NS); + exportAttributes(page); - Element title = page.newChildElement("bebop:title", BEBOP_XML_NS); - title.setText(getTitle(ps).getLabel(ps)); + /* Generator information */ + exportSystemInformation(page); - for (Iterator i = m_clientStylesheets.iterator(); i.hasNext();) { - ((Stylesheet) i.next()).generateXML(page); - } + Element title = page.newChildElement("bebop:title", BEBOP_XML_NS); + title.setText(getTitle(ps).getLabel(ps)); - return page; - } + for (Iterator i = m_clientStylesheets.iterator(); i.hasNext();) { + ((Stylesheet) i.next()).generateXML(page); + } - /** - * Constructs a DOM or JDOM tree with all components on the page. The tree - * represents the page that results from the - * {@link javax.servlet.http.HttpServletRequest} kept in the - * state. - * - * @param state the page state produced by {@link #process} - * @param parent the DOM node for the whole Document - * @see #process process - * @pre isLocked() - * @pre state != null - */ - public void generateXML(PageState state, Document parent) { - // always export page state as HTTP session - if (m_useHttpSession) { - state.stateAsHttpSession(); - } + return page; + } - Element page = generateXMLHelper(state, parent); + /** + * Constructs a DOM or JDOM tree with all components on the page. The + * tree represents the page that results from the + * {@link javax.servlet.http.HttpServletRequest} kept in the + * state. + * + * @param state the page state produced by {@link #process} + * @param parent the DOM node for the whole Document + * @see #process process + * @pre isLocked() + * @pre state != null + */ + public void generateXML(PageState state, Document parent) { + // always export page state as HTTP session + if (m_useHttpSession) { + state.stateAsHttpSession(); + } - // If the page state has errors, ignore all the components and - // render only the error display component - if (state.getErrors().hasNext()) { - m_errorDisplay.generateXML(state, page); - } else { - m_panel.generateXML(state, page); - } + Element page = generateXMLHelper(state, parent); - if (Kernel.getConfig().isDebugEnabled() && debugStructure(state. - getRequest())) { + // If the page state has errors, ignore all the components and + // render only the error display component + if (state.getErrors().hasNext()) { + m_errorDisplay.generateXML(state, page); + } else { + m_panel.generateXML(state, page); + } - Element structure = - page.newChildElement("bebop:structure", BEBOP_XML_NS); + if (Kernel.getConfig().isDebugEnabled() && debugStructure(state. + getRequest())) { - showStructure(state, structure); - } - } + Element structure = + page.newChildElement("bebop:structure", BEBOP_XML_NS); - private static boolean debugStructure(HttpServletRequest req) { - return "transform".equals(req.getParameter("debug")); - } + showStructure(state, structure); + } + } - /** - * Do nothing. Top-level add nodes is meaningless. - */ - public void generateXML(PageState state, Element elt) { - return; - } + private static boolean debugStructure(HttpServletRequest req) { + return "transform".equals(req.getParameter("debug")); + } - /** - * Creates a PageState object and processes it by calling the respond method - * on the selected component. Processes a request by notifying the component - * from which the process originated and {@link #fireActionEvent - * broadcasts} an {@link ActionEvent} to all the listeners that registered - * with {@link #addActionListener addActionListener}. - * - * @see #generateXML(PageState,Document) generateXML - * @pre isLocked() - * @pre request != null - * @pre response != null - */ - public PageState process(HttpServletRequest request, - HttpServletResponse response) - throws ServletException { + /** + * Do nothing. Top-level add nodes is meaningless. + */ + @Override + public void generateXML(PageState state, Element elt) { + } - PageState result = new PageState(this, request, response); - try { - DeveloperSupport.startStage("Bebop Page Process"); - process(result); - } finally { - DeveloperSupport.endStage("Bebop Page Process"); - } - return result; - } + /** + * Creates a PageState object and processes it by calling the respond + * method on the selected component. Processes a request by notifying + * the component from which the process originated and {@link #fireActionEvent + * broadcasts} an {@link ActionEvent} to all the listeners that + * registered with {@link #addActionListener addActionListener}. + * + * @see #generateXML(PageState,Document) generateXML + * @pre isLocked() + * @pre request != null + * @pre response != null + */ + public PageState process(HttpServletRequest request, + HttpServletResponse response) + throws ServletException { - /** - * Processes the supplied PageState object according to this PageModel. - * Calls the respond method on the selected Bebop component. - */ - public void process(PageState state) throws ServletException { - Assert.isLocked(this); - try { - DeveloperSupport.startStage("Bebop Request Event"); - fireRequestEvent(state); - } finally { - DeveloperSupport.endStage("Bebop Request Event"); - } + PageState result = new PageState(this, request, response); + try { + DeveloperSupport.startStage("Bebop Page Process"); + process(result); + } finally { + DeveloperSupport.endStage("Bebop Page Process"); + } + return result; + } - // Validate the state; any errors in the state will be displayed - // by generateXML - state.forceValidate(); + /** + * Processes the supplied PageState object according to this PageModel. + * Calls the respond method on the selected Bebop component. + */ + public void process(PageState state) throws ServletException { + Assert.isLocked(this); + try { + DeveloperSupport.startStage("Bebop Request Event"); + fireRequestEvent(state); + } finally { + DeveloperSupport.endStage("Bebop Request Event"); + } - if (state.isValid()) { - try { - DeveloperSupport.startStage("Bebop Respond"); - state.respond(); - } finally { - DeveloperSupport.endStage("Bebop Respond"); - } - try { - DeveloperSupport.startStage("Bebop Action Event"); - fireActionEvent(state); - } finally { - DeveloperSupport.endStage("Bebop Action Event"); - } - } - } + // Validate the state; any errors in the state will be displayed + // by generateXML + state.forceValidate(); + + if (state.isValid()) { + try { + DeveloperSupport.startStage("Bebop Respond"); + state.respond(); + } finally { + DeveloperSupport.endStage("Bebop Respond"); + } + try { + DeveloperSupport.startStage("Bebop Action Event"); + fireActionEvent(state); + } finally { + DeveloperSupport.endStage("Bebop Action Event"); + } + } + } // /** // * Does all the servicing of a request except output generation. @@ -695,619 +707,627 @@ public class Page extends BlockStylable implements Container { // PageState state = process(req, res); // return state; // } - /** - * Builds a DOM Document from the current request state by doing a - * depth-first tree walk on the current set of components in this Page, - * calling generateXML on each. Does NOT do the rendering. If the HTTP - * response has already been committed, does not build the XML document. - * - * @return a DOM ready for rendering, or null if the response has already - * been committed. - * @post res.isCommitted() == (return == null) - */ - public Document buildDocument(HttpServletRequest req, - HttpServletResponse res) - throws ServletException { - try { - Document doc = new Document(); - PageState state = process(req, res); - - // only generate XML document if the response is not already - // committed - if (!res.isCommitted()) { - try { - DeveloperSupport.startStage("Bebop XML"); - Profiler.startOp("XML"); - generateXML(state, doc); - } finally { - DeveloperSupport.endStage("Bebop XML"); - Profiler.stopOp("XML"); - } - return doc; - } else { - return null; - } - } catch (ParserConfigurationException e) { - throw new ServletException(e); - } - } - - /** - * Finishes building the page. The tree of components is traversed and each - * component is told to add its state parameters to the page's state model. - * - * @pre ! isLocked() - */ - private void finish() { - if (!m_finished) { - Assert.isUnlocked(this); - - Traversal componentRegistrar = new Traversal() { - protected void act(Component c) { - addComponent(c); - c.register(Page.this); - } - }; - if (m_panel == null) { - s_log.warn("m_panel is null"); - } - componentRegistrar.preorder(m_panel); - if (m_errorDisplay != null) { - addComponent(m_errorDisplay); - m_errorDisplay.register(Page.this); - } - - m_finished = true; - } - } - - /** - * Locks the page and all its components against further modifications. - * - *

Locking a page helps in finding mistakes that result from modifying a - * page's structure.

- */ - public void lock() { - if (!m_finished) { - finish(); - } - m_stateModel.lock(); - Traversal componentLocker = new Traversal() { - protected void act(Component c) { - c.lock(); - } - }; - - componentLocker.preorder(m_panel); - - super.lock(); - } - - public void respond(PageState state) throws javax.servlet.ServletException { - throw new UnsupportedOperationException(); - } - - /** - * Registers a listener that is notified whenever a request to this page is - * made, after the selected component has had a chance to respond. - * - * @pre l != null - * @pre ! isLocked() - */ - public void addActionListener(ActionListener l) { - Assert.isUnlocked(this); - m_actionListeners.add(l); - } - - /** - * Remove a previously registered action listener. - * - * @pre l != null - * @pre ! isLocked() - */ - public void removeActionListener(ActionListener l) { - Assert.isUnlocked(this); - m_actionListeners.remove(l); - } - - /** - * Registers a listener that is notified whenever a request to this page is - * made, before the selected component has had a chance to respond. - * - * @pre l != null - * @pre ! isLocked() - */ - public void addRequestListener(RequestListener l) { - Assert.isUnlocked(this); - m_requestListeners.add(l); - } - - /** - * Removes a previously registered request listener. - * - * @param 1 the listener to remove - * @pre l != null - * @pre ! isLocked() - */ - public void removeRequestListener(RequestListener l) { - Assert.isUnlocked(this); - m_requestListeners.remove(l); - } - - /** - * Broadcasts an {@link ActionEvent} to all registered listeners. The source - * of the event is this page, and the state recorded in the event is the one - * resulting from processing the current request. - * - * @param the state for this event - * - * @pre state != null - */ - protected void fireActionEvent(PageState state) { - ActionEvent e = null; - - for (Iterator i = m_actionListeners.iterator(); i.hasNext();) { - if (e == null) { - e = new ActionEvent(this, state); - } - - final ActionListener listener = (ActionListener) i.next(); - - if (s_log.isDebugEnabled()) { - s_log.debug("Firing action listener " + listener); - } - - listener.actionPerformed(e); - } - } - - /** - * Broadcasts a {@link RequestEvent} to all registered listeners. The source - * of the event is this page, and the state recorded in the event is the one - * resulting from processing the current request. - * - * @param state the state for this event - * - * @pre state != null - */ - protected void fireRequestEvent(PageState state) { - RequestEvent e = null; - - for (Iterator i = m_requestListeners.iterator(); i.hasNext();) { - if (e == null) { - e = new RequestEvent(this, state); - } - - final RequestListener listener = (RequestListener) i.next(); - - if (s_log.isDebugEnabled()) { - s_log.debug("Firing request listener " + listener); - } - - listener.pageRequested(e); - } - } - - /** - * Export page generator information if set. The m_pageGenerator is a - * HashMap containing the information as key value. In general this should - * include generator name and generator version. - * - * @param page parent element - should be bebeop:page - * - * @pre m_pageGenerator != null && !m_pageGenerator.isEmpty() - */ - final protected void exportSystemInformation(Element page) { - SystemInformation sysInfo = SystemInformation.getInstance(); - if (!sysInfo.isEmpty()) { - Element gen = page.newChildElement("bebop:systemInformation", BEBOP_XML_NS); - - Iterator> keyValues = sysInfo.iterator(); - while (keyValues.hasNext()) { - Map.Entry entry = keyValues.next(); - gen.addAttribute(entry.getKey(), entry.getValue()); - } - } - } - - // Client-side stylesheet storage - private class Stylesheet { - - String m_URI; - String m_type; - - public Stylesheet(String stylesheetURI, String mimeType) { - m_URI = stylesheetURI; - m_type = mimeType; - } - - public void generateXML(Element parent) { - Element style = parent.newChildElement("bebop:stylesheet", - BEBOP_XML_NS); - style.addAttribute("href", m_URI); - if (m_type != null) { - style.addAttribute("type", m_type); - } - } - } - - /** - * Adds a component to the page model. - * - * @deprecated This method will become private in ACS 5.0. - */ - public void addComponent(Component c) { - Assert.isUnlocked(this); - - if (!stateContains(c)) { - if (c == null) { - s_log.error("c is null"); - } /*else { - s_log.error("c: " + c.toString()); - }*/ - String key = c.getKey(); - if (key == null) { - key = Integer.toString(m_components.size()); - } - if (m_componentMap.get(key) != null) { - throw new IllegalArgumentException( - "Component key must not be duplicated. The key " + key - + " is shared by more than one component."); - } - m_componentMap.put(key, c); - m_components.add(c); - } - } - - /** - * Registers a state parameter for a component. It is permissible to - * register the same state parameter several times, from the same or - * different components. The name of the parameter will be changed to ensure - * that it won't clash with any other component's parameter. If the - * parameter is added more than once, the name is only changed the first - * time it is added. - * - * @param c the component to register the parameter for - * @param p the state parameter to register - * - * @see #addGlobalStateParam - * - * @pre stateContains(c) - * @pre ! isLocked() - * @pre p != null - */ - public void addComponentStateParam(Component c, ParameterModel p) { - Assert.isUnlocked(this); - - if (!stateContains(c)) { - throw new IllegalArgumentException( - "Component must be registered in Page"); - } - if (!m_stateModel.containsFormParam(p)) { - String name = parameterName(c, p.getName()); - s_log.debug(String.format("Setting name of parameter to add to '%s'", - name)); - p.setName(name); - m_stateModel.addFormParam(p); - - Collection params = (Collection) m_componentParameterMap.get(c); - if (params == null) { - params = new ArrayList(); - m_componentParameterMap.put(c, params); - } - params.add(p); - } - } - - /** - *

Get the parameters registered for a given component.

- */ - public Collection getComponentParameters(Component c) { - return (Collection) m_componentParameterMap.get(c); - } - - /** - * Gets the state index of a component. This is the number assigned to the - * component in the register traveral - * - * @param c the component to search for - * - * @return the index in this list of the first occurrence of the specified - * element, or -1 if this list does not contain this element. - * - * @pre c != null - * @post contains(c) implies (return >= 0) && (return < size()) - * @post !contains(c) implies return == -1 - */ - public int stateIndex(Component c) { - return m_components.indexOf(c); - } - - /** - * The number of components in the page model. - * - * @post return >= 0 - */ - public int stateSize() { - return m_components.size(); - } - - /** - * Checks whether this component is already in the page model. - * - * @pre c != null - */ - public boolean stateContains(Component c) { - return m_components.contains(c); - } - - /** - * Gets a page component by index. - * - * @pre (i >= 0) && (i < size()) - * @post return != null - */ - public Component getComponent(int i) { - return (Component) m_components.get(i); - } - - /** - * Gets a page component by key. - * - * @pre s != null - */ - Component getComponent(String s) { - return (Component) m_componentMap.get(s); - } - - /** - * Gets the form model that contains the parameters for the page's state. - */ - public final FormModel getStateModel() { - return m_stateModel; - } - - /** - * Gets the ParameterModels held in this Page. - * - * @return an iterator of ParameterModels. - */ - public Iterator getParameters() { - return m_stateModel.getParameters(); - } - - /** - * Checks whether the specified component is visible by default on the page. - * - * @param c a component contained in the page - * @return true if the component is visible by default; - * false otherwise. - * @see #setVisibleDefault setVisibleDefault - * @see Component#setVisible Component.setVisible - */ - public boolean isVisibleDefault(Component c) { - Assert.isTrue(stateContains(c)); - - return !m_invisible.get(stateIndex(c)); - } - - /** - * Sets whether the specified component is visible by default. The default - * visibility is used when a page is displayed for the first time and on - * subsequent requests until the visibility of a component is changed - * explicitly with {@link Component#setVisible - * Component.setVisible}. - * - *

When a component is first added to a page, it is visible. - * - * @param c a component whose visibility is to be set - * @param v true if the component is visible; - * false otherwise. - * @see Component#setVisible Component.setVisible - * @see Component#register Component.register - */ - public void setVisibleDefault(Component c, boolean v) { - Assert.isUnlocked(this); - - addComponent(c); - int i = stateIndex(c); - if (v) { - m_invisible.clear(i); - } else { - m_invisible.set(i); - } - } - - /** - * The global name of the parameter - * name in the component - * c. - */ - public String parameterName(Component c, String name) { - if (c == null || !stateContains(c)) { - return name; - } - - return componentPrefix(c) + name; - } - - /** - * The global name of the parameter - * name. - */ - public String parameterName(String name) { - return parameterName(null, name); - } - - void reset(final PageState ps, Component cmpnt) { - Traversal resetter = new Traversal() { - protected void act(Component c) { - Collection cp = getComponentParameters(c); - if (cp != null) { - Iterator iter = cp.iterator(); - while (iter.hasNext()) { - ParameterModel p = (ParameterModel) iter.next(); - ps.setValue(p, null); - } - } - c.setVisible(ps, isVisibleDefault(c)); - } - }; - resetter.preorder(cmpnt); - } - - /** - * Return the prefix that is prepended to each component's state parameters - * to keep them unique. - */ - private final String componentPrefix(Component c) { - if (c == null) { - return COMPONENT_PREFIX + "g" + DELIMITER; - } else { - // WRS: preferentially use key if it exists - String key = c.getKey(); - if (key == null) { - if (stateContains(c)) { - key = String.valueOf(stateIndex(c)); - } else { - throw new IllegalArgumentException( - "Cannot generate prefix for component: key is null " - + "and component " + c.toString() + "/" + c.getKey() - + " did not register with page."); - } - } - return COMPONENT_PREFIX + key + DELIMITER; - } - } - - /** - * Undo the name change that {@link #parameterName} does. - * - * @param name a possibly mangled name - * @return the unmangled name. - */ - private static final String unmangle(String name) { - if (!name.startsWith(COMPONENT_PREFIX)) { - return name; - } - // Find the second occurence of delimiter - int prefix = name.indexOf(DELIMITER, name.indexOf(DELIMITER) + 1); - if (prefix >= 0 && prefix < name.length()) { - return name.substring(prefix + 1); - } - return name; - } - // Procs for debugging output - private static String NAME = "name"; - - /** - * Produces an XML fragment that captures the layout of this page. - */ - private void showStructure(PageState s, Element root) { - final HttpServletRequest req = s.getRequest(); - Element state = root.newChildElement("bebop:state", BEBOP_XML_NS); - // Selected component - String sel = req.getParameter(m_selected.getName()); - Element selected = state.newChildElement("bebop:selected", BEBOP_XML_NS); - - selected.addAttribute(NAME, m_selected.getName()); - selected.setText(sel); - - // Control event - Element eventName = - state.newChildElement("bebop:eventName", BEBOP_XML_NS); - eventName.addAttribute(NAME, m_controlEvent.getName()); - eventName.setText(req.getParameter(m_controlEvent.getName())); - Element eventValue = - state.newChildElement("bebop:eventValue", BEBOP_XML_NS); - eventValue.addAttribute(NAME, m_controlValue.getName()); - eventValue.setText(req.getParameter(m_controlValue.getName())); - - // Global parameters - Element globalState = - root.newChildElement("bebop:params", BEBOP_XML_NS); - for (Iterator ii = getStateModel().getParameters(); ii.hasNext();) { - ParameterModel p = (ParameterModel) ii.next(); - if (!p.getName().startsWith(COMPONENT_PREFIX)) { - Element param = - globalState.newChildElement("bebop:param", BEBOP_XML_NS); - param.addAttribute(NAME, p.getName()); - param.setText(String.valueOf(s.getValue(p))); - } - } - - showVisibility(s, this, root); - } - - /** - * @see showStructure(PageState, Element) - */ - private void showVisibility(PageState s, Component c, Element parent) { - HttpServletRequest req = s.getRequest(); - - Element cmp = parent.newChildElement("bebop:component", BEBOP_XML_NS); - cmp.addAttribute(NAME, getDebugLabel(c)); - cmp.addAttribute("idx", String.valueOf(stateIndex(c))); - cmp.addAttribute("isVisible", (s.isVisible(c) ? "yes" : "no")); - cmp.addAttribute("class", c.getClass().getName()); - - if (c.getKey() != null) { - String prefix = componentPrefix(c); - for (Iterator i = getStateModel().getParameters(); i.hasNext();) { - ParameterModel p = (ParameterModel) i.next(); - if (!p.getName().startsWith(prefix)) { - continue; - } - - Element param = - parent.newChildElement("bebop:param", BEBOP_XML_NS); - param.addAttribute(NAME, unmangle(p.getName())); - param.addAttribute("defaultValue", - String.valueOf(req.getParameter(p.getName()))); - param.addAttribute("currentValue", String.valueOf(s.getValue(p))); - } - } - for (Iterator i = c.children(); i.hasNext();) { - showVisibility(s, ((Component) i.next()), cmp); - } - } - - private static String getDebugLabel(Component c) { - if (c.getKey() != null) { - return c.getKey(); - } - - String klass = c.getClass().getName(); - return klass.substring(klass.lastIndexOf(".") + 1, klass.length()); - } - - /** - * return a string that represents an ordered list of component ids used on - * the page. For situations where only the components present is of - * importance, this may be used by implementations of hashCode & equals - * - * @return - */ - public String getComponentString() { - Iterator it = m_componentMap.keySet().iterator(); - /*int hash = 0; - while (it.hasNext()) { - String componentId = (String)it.next(); - s_log.debug("component id = " + componentId); - hash = hash | componentId.hashCode(); - s_log.debug("hash so far = " + hash); - }*/ - Date start = new Date(); - - StringBuffer hashString = new StringBuffer(); - while (it.hasNext()) { - String componentId = (String) it.next(); - hashString.append(componentId); - } - s_log.debug("Time to create hashCode for page: " + (new Date().getTime() - start. - getTime())); - return hashString.toString(); - - - } + /** + * Builds a DOM Document from the current request state by doing a + * depth-first tree walk on the current set of components in this Page, + * calling generateXML on each. Does NOT do the rendering. If the HTTP + * response has already been committed, does not build the XML document. + * + * @return a DOM ready for rendering, or null if the response has + * already been committed. + * @post res.isCommitted() == (return == null) + */ + public Document buildDocument(HttpServletRequest req, + HttpServletResponse res) + throws ServletException { + try { + Document doc = new Document(); + PageState state = process(req, res); + + // only generate XML document if the response is not already + // committed + if (!res.isCommitted()) { + try { + DeveloperSupport.startStage("Bebop XML"); + Profiler.startOp("XML"); + generateXML(state, doc); + } finally { + DeveloperSupport.endStage("Bebop XML"); + Profiler.stopOp("XML"); + } + return doc; + } else { + return null; + } + } catch (ParserConfigurationException e) { + throw new ServletException(e); + } + } + + /** + * Finishes building the page. The tree of components is traversed and + * each component is told to add its state parameters to the page's + * state model. + * + * @pre ! isLocked() + */ + private void finish() { + if (!m_finished) { + Assert.isUnlocked(this); + + Traversal componentRegistrar = new Traversal() { + @Override + protected void act(Component c) { + addComponent(c); + c.register(Page.this); + } + }; + if (m_panel == null) { + s_log.warn("m_panel is null"); + } + componentRegistrar.preorder(m_panel); + if (m_errorDisplay != null) { + addComponent(m_errorDisplay); + m_errorDisplay.register(Page.this); + } + + m_finished = true; + } + } + + /** + * Locks the page and all its components against further modifications. + * + *

Locking a page helps in finding mistakes that result from + * modifying a page's structure.

+ */ + @Override + public void lock() { + if (!m_finished) { + finish(); + } + m_stateModel.lock(); + Traversal componentLocker = new Traversal() { + @Override + protected void act(Component c) { + c.lock(); + } + }; + + componentLocker.preorder(m_panel); + + super.lock(); + } + + @Override + public void respond(PageState state) throws javax.servlet.ServletException { + throw new UnsupportedOperationException(); + } + + /** + * Registers a listener that is notified whenever a request to this page + * is made, after the selected component has had a chance to respond. + * + * @pre l != null + * @pre ! isLocked() + */ + public void addActionListener(ActionListener l) { + Assert.isUnlocked(this); + m_actionListeners.add(l); + } + + /** + * Remove a previously registered action listener. + * + * @pre l != null + * @pre ! isLocked() + */ + public void removeActionListener(ActionListener l) { + Assert.isUnlocked(this); + m_actionListeners.remove(l); + } + + /** + * Registers a listener that is notified whenever a request to this page + * is made, before the selected component has had a chance to respond. + * + * @pre l != null + * @pre ! isLocked() + */ + public void addRequestListener(RequestListener l) { + Assert.isUnlocked(this); + m_requestListeners.add(l); + } + + /** + * Removes a previously registered request listener. + * + * @param 1 the listener to remove + * @pre l != null + * @pre ! isLocked() + */ + public void removeRequestListener(RequestListener l) { + Assert.isUnlocked(this); + m_requestListeners.remove(l); + } + + /** + * Broadcasts an {@link ActionEvent} to all registered listeners. The + * source of the event is this page, and the state recorded in the event + * is the one resulting from processing the current request. + * + * @param the state for this event + * + * @pre state != null + */ + protected void fireActionEvent(PageState state) { + ActionEvent e = null; + + for (Iterator i = m_actionListeners.iterator(); i.hasNext();) { + if (e == null) { + e = new ActionEvent(this, state); + } + + final ActionListener listener = (ActionListener) i.next(); + + if (s_log.isDebugEnabled()) { + s_log.debug("Firing action listener " + listener); + } + + listener.actionPerformed(e); + } + } + + /** + * Broadcasts a {@link RequestEvent} to all registered listeners. The + * source of the event is this page, and the state recorded in the event + * is the one resulting from processing the current request. + * + * @param state the state for this event + * + * @pre state != null + */ + protected void fireRequestEvent(PageState state) { + RequestEvent e = null; + + for (Iterator i = m_requestListeners.iterator(); i.hasNext();) { + if (e == null) { + e = new RequestEvent(this, state); + } + + final RequestListener listener = (RequestListener) i.next(); + + if (s_log.isDebugEnabled()) { + s_log.debug("Firing request listener " + listener); + } + + listener.pageRequested(e); + } + } + + /** + * Export page generator information if set. The m_pageGenerator is a + * HashMap containing the information as key value. In general this + * should include generator name and generator version. + * + * @param page parent element - should be bebeop:page + * + * @pre m_pageGenerator != null && !m_pageGenerator.isEmpty() + */ + final protected void exportSystemInformation(Element page) { + SystemInformation sysInfo = SystemInformation.getInstance(); + if (!sysInfo.isEmpty()) { + Element gen = page.newChildElement("bebop:systemInformation", BEBOP_XML_NS); + + Iterator> keyValues = sysInfo.iterator(); + while (keyValues.hasNext()) { + Map.Entry entry = keyValues.next(); + gen.addAttribute(entry.getKey(), entry.getValue()); + } + } + } + + // Client-side stylesheet storage + private class Stylesheet { + + String m_URI; + String m_type; + + public Stylesheet(String stylesheetURI, String mimeType) { + m_URI = stylesheetURI; + m_type = mimeType; + } + + public void generateXML(Element parent) { + Element style = parent.newChildElement("bebop:stylesheet", + BEBOP_XML_NS); + style.addAttribute("href", m_URI); + if (m_type != null) { + style.addAttribute("type", m_type); + } + } + } + + /** + * Adds a component to the page model. + * + * @deprecated This method will become private in ACS 5.0. + */ + public void addComponent(Component c) { + Assert.isUnlocked(this); + + if (!stateContains(c)) { + if (c == null) { + s_log.error("c is null"); + } /*else { + s_log.error("c: " + c.toString()); + }*/ + String key = c.getKey(); + if (key == null) { + key = Integer.toString(m_components.size()); + } + if (m_componentMap.get(key) != null) { + throw new IllegalArgumentException( + "Component key must not be duplicated. The key " + key + + " is shared by more than one component."); + } + m_componentMap.put(key, c); + m_components.add(c); + } + } + + /** + * Registers a state parameter for a component. It is permissible to + * register the same state parameter several times, from the same or + * different components. The name of the parameter will be changed to + * ensure that it won't clash with any other component's parameter. If + * the parameter is added more than once, the name is only changed the + * first time it is added. + * + * @param c the component to register the parameter for + * @param p the state parameter to register + * + * @see #addGlobalStateParam + * + * @pre stateContains(c) + * @pre ! isLocked() + * @pre p != null + */ + public void addComponentStateParam(Component c, ParameterModel p) { + Assert.isUnlocked(this); + + if (!stateContains(c)) { + throw new IllegalArgumentException( + "Component must be registered in Page"); + } + if (!m_stateModel.containsFormParam(p)) { + String name = parameterName(c, p.getName()); + s_log.debug(String.format("Setting name of parameter to add to '%s'", + name)); + p.setName(name); + m_stateModel.addFormParam(p); + + Collection params = (Collection) m_componentParameterMap.get(c); + if (params == null) { + params = new ArrayList(); + m_componentParameterMap.put(c, params); + } + params.add(p); + } + } + + /** + *

Get the parameters registered for a given component.

+ */ + public Collection getComponentParameters(Component c) { + return (Collection) m_componentParameterMap.get(c); + } + + /** + * Gets the state index of a component. This is the number assigned to + * the component in the register traveral + * + * @param c the component to search for + * + * @return the index in this list of the first occurrence of the + * specified element, or -1 if this list does not contain this element. + * + * @pre c != null + * @post contains(c) implies (return >= 0) && (return < size()) + * @post !contains(c) implies return == -1 + */ + public int stateIndex(Component c) { + return m_components.indexOf(c); + } + + /** + * The number of components in the page model. + * + * @post return >= 0 + */ + public int stateSize() { + return m_components.size(); + } + + /** + * Checks whether this component is already in the page model. + * + * @pre c != null + */ + public boolean stateContains(Component c) { + return m_components.contains(c); + } + + /** + * Gets a page component by index. + * + * @pre (i >= 0) && (i < size()) + * @post return != null + */ + public Component getComponent(int i) { + return (Component) m_components.get(i); + } + + /** + * Gets a page component by key. + * + * @pre s != null + */ + Component getComponent(String s) { + return (Component) m_componentMap.get(s); + } + + /** + * Gets the form model that contains the parameters for the page's + * state. + */ + public final FormModel getStateModel() { + return m_stateModel; + } + + /** + * Gets the ParameterModels held in this Page. + * + * @return an iterator of ParameterModels. + */ + public Iterator getParameters() { + return m_stateModel.getParameters(); + } + + /** + * Checks whether the specified component is visible by default on the + * page. + * + * @param c a component contained in the page + * @return true if the component is visible by default; + * false otherwise. + * @see #setVisibleDefault setVisibleDefault + * @see Component#setVisible Component.setVisible + */ + public boolean isVisibleDefault(Component c) { + Assert.isTrue(stateContains(c)); + + return !m_invisible.get(stateIndex(c)); + } + + /** + * Sets whether the specified component is visible by default. The + * default visibility is used when a page is displayed for the first + * time and on subsequent requests until the visibility of a component + * is changed explicitly with {@link Component#setVisible + * Component.setVisible}. + * + *

When a component is first added to a page, it is visible. + * + * @param c a component whose visibility is to be set + * @param v true if the component is visible; + * false otherwise. + * @see Component#setVisible Component.setVisible + * @see Component#register Component.register + */ + public void setVisibleDefault(Component c, boolean v) { + Assert.isUnlocked(this); + + addComponent(c); + int i = stateIndex(c); + if (v) { + m_invisible.clear(i); + } else { + m_invisible.set(i); + } + } + + /** + * The global name of the parameter + * name in the component + * c. + */ + public String parameterName(Component c, String name) { + if (c == null || !stateContains(c)) { + return name; + } + + return componentPrefix(c) + name; + } + + /** + * The global name of the parameter + * name. + */ + public String parameterName(String name) { + return parameterName(null, name); + } + + void reset(final PageState ps, Component cmpnt) { + Traversal resetter = new Traversal() { + @Override + protected void act(Component c) { + Collection cp = getComponentParameters(c); + if (cp != null) { + Iterator iter = cp.iterator(); + while (iter.hasNext()) { + ParameterModel p = (ParameterModel) iter.next(); + ps.setValue(p, null); + } + } + c.setVisible(ps, isVisibleDefault(c)); + } + }; + resetter.preorder(cmpnt); + } + + /** + * Return the prefix that is prepended to each component's state + * parameters to keep them unique. + */ + private final String componentPrefix(Component c) { + if (c == null) { + return COMPONENT_PREFIX + "g" + DELIMITER; + } else { + // WRS: preferentially use key if it exists + String key = c.getKey(); + if (key == null) { + if (stateContains(c)) { + key = String.valueOf(stateIndex(c)); + } else { + throw new IllegalArgumentException( + "Cannot generate prefix for component: key is null " + + "and component " + c.toString() + "/" + c.getKey() + + " did not register with page."); + } + } + return COMPONENT_PREFIX + key + DELIMITER; + } + } + + /** + * Undo the name change that {@link #parameterName} does. + * + * @param name a possibly mangled name + * @return the unmangled name. + */ + private static final String unmangle(String name) { + if (!name.startsWith(COMPONENT_PREFIX)) { + return name; + } + // Find the second occurence of delimiter + int prefix = name.indexOf(DELIMITER, name.indexOf(DELIMITER) + 1); + if (prefix >= 0 && prefix < name.length()) { + return name.substring(prefix + 1); + } + return name; + } + // Procs for debugging output + private static String NAME = "name"; + + /** + * Produces an XML fragment that captures the layout of this page. + */ + private void showStructure(PageState s, Element root) { + final HttpServletRequest req = s.getRequest(); + Element state = root.newChildElement("bebop:state", BEBOP_XML_NS); + // Selected component + String sel = req.getParameter(m_selected.getName()); + Element selected = state.newChildElement("bebop:selected", BEBOP_XML_NS); + + selected.addAttribute(NAME, m_selected.getName()); + selected.setText(sel); + + // Control event + Element eventName = + state.newChildElement("bebop:eventName", BEBOP_XML_NS); + eventName.addAttribute(NAME, m_controlEvent.getName()); + eventName.setText(req.getParameter(m_controlEvent.getName())); + Element eventValue = + state.newChildElement("bebop:eventValue", BEBOP_XML_NS); + eventValue.addAttribute(NAME, m_controlValue.getName()); + eventValue.setText(req.getParameter(m_controlValue.getName())); + + // Global parameters + Element globalState = + root.newChildElement("bebop:params", BEBOP_XML_NS); + for (Iterator ii = getStateModel().getParameters(); ii.hasNext();) { + ParameterModel p = (ParameterModel) ii.next(); + if (!p.getName().startsWith(COMPONENT_PREFIX)) { + Element param = + globalState.newChildElement("bebop:param", BEBOP_XML_NS); + param.addAttribute(NAME, p.getName()); + param.setText(String.valueOf(s.getValue(p))); + } + } + + showVisibility(s, this, root); + } + + /** + * @see showStructure(PageState, Element) + */ + private void showVisibility(PageState s, Component c, Element parent) { + HttpServletRequest req = s.getRequest(); + + Element cmp = parent.newChildElement("bebop:component", BEBOP_XML_NS); + cmp.addAttribute(NAME, getDebugLabel(c)); + cmp.addAttribute("idx", String.valueOf(stateIndex(c))); + cmp.addAttribute("isVisible", (s.isVisible(c) ? "yes" : "no")); + cmp.addAttribute("class", c.getClass().getName()); + + if (c.getKey() != null) { + String prefix = componentPrefix(c); + for (Iterator i = getStateModel().getParameters(); i.hasNext();) { + ParameterModel p = (ParameterModel) i.next(); + if (!p.getName().startsWith(prefix)) { + continue; + } + + Element param = + parent.newChildElement("bebop:param", BEBOP_XML_NS); + param.addAttribute(NAME, unmangle(p.getName())); + param.addAttribute("defaultValue", + String.valueOf(req.getParameter(p.getName()))); + param.addAttribute("currentValue", String.valueOf(s.getValue(p))); + } + } + for (Iterator i = c.children(); i.hasNext();) { + showVisibility(s, ((Component) i.next()), cmp); + } + } + + private static String getDebugLabel(Component c) { + if (c.getKey() != null) { + return c.getKey(); + } + + String klass = c.getClass().getName(); + return klass.substring(klass.lastIndexOf(".") + 1, klass.length()); + } + + /** + * return a string that represents an ordered list of component ids used + * on the page. For situations where only the components present is of + * importance, this may be used by implementations of hashCode & equals + * + * @return + */ + public String getComponentString() { + Iterator it = m_componentMap.keySet().iterator(); + /*int hash = 0; + while (it.hasNext()) { + String componentId = (String)it.next(); + s_log.debug("component id = " + componentId); + hash = hash | componentId.hashCode(); + s_log.debug("hash so far = " + hash); + }*/ + Date start = new Date(); + + StringBuilder hashString = new StringBuilder(); + while (it.hasNext()) { + String componentId = (String) it.next(); + hashString.append(componentId); + } + s_log.debug("Time to create hashCode for page: " + (new Date().getTime() - start. + getTime())); + return hashString.toString(); + + + } } diff --git a/ccm-core/src/com/arsdigita/bebop/SaveCancelSection.java b/ccm-core/src/com/arsdigita/bebop/SaveCancelSection.java index e9de84a03..b9e6d20c1 100755 --- a/ccm-core/src/com/arsdigita/bebop/SaveCancelSection.java +++ b/ccm-core/src/com/arsdigita/bebop/SaveCancelSection.java @@ -26,7 +26,7 @@ import com.arsdigita.bebop.util.GlobalizationUtil; * the right. * * @author Stanislav Freidin - * @author Sören Bernstein (sbernstein@quasiweb.de) + * @author Sören Bernstein * @version $Id: SaveCancelSection.java 287 2005-02-22 00:29:02Z sskracic $ */ public class SaveCancelSection extends FormSection { diff --git a/ccm-core/src/com/arsdigita/bebop/form/Date.java b/ccm-core/src/com/arsdigita/bebop/form/Date.java index d54b33920..9b630926b 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/Date.java +++ b/ccm-core/src/com/arsdigita/bebop/form/Date.java @@ -48,7 +48,7 @@ import java.util.Locale; * @author Karl Goldstein * @author Uday Mathur * @author Michael Pih - * @author Sören Bernstein + * @author Sören Bernstein * @version $Id: Date.java 288 2010-02-20 07:29:00Z sbernstein $ */ public class Date extends Widget implements BebopConstants { diff --git a/ccm-core/src/com/arsdigita/bebop/form/DateTime.java b/ccm-core/src/com/arsdigita/bebop/form/DateTime.java index 2e804b758..159610ab3 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/DateTime.java +++ b/ccm-core/src/com/arsdigita/bebop/form/DateTime.java @@ -30,7 +30,7 @@ import com.arsdigita.xml.Element; * A class representing a date and time field in an HTML form. * (based on the code in Date.java) * - * @author Sören Bernstein + * @author Sören Bernstein * @version $Id: DateTime.java 288 2010-02-20 07:29:00Z ssbernstein $ */ public class DateTime extends Widget implements BebopConstants { diff --git a/ccm-core/src/com/arsdigita/bebop/form/Time.java b/ccm-core/src/com/arsdigita/bebop/form/Time.java index 4494d8c69..030d1efec 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/Time.java +++ b/ccm-core/src/com/arsdigita/bebop/form/Time.java @@ -38,7 +38,7 @@ import java.util.Locale; * * @see com.arsdigita.bebop.form.DateTime * @author Dave Turner - * @author Sören Bernstein + * @author Sören Bernstein * @version $Id: Time.java 288 2010-02-20 07:29:00Z sbernstein $ */ public class Time extends Widget implements BebopConstants { diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/IncompleteDateParameter.java b/ccm-core/src/com/arsdigita/bebop/parameters/IncompleteDateParameter.java index 2a5fad7c3..660088a16 100644 --- a/ccm-core/src/com/arsdigita/bebop/parameters/IncompleteDateParameter.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/IncompleteDateParameter.java @@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletRequest; * combination with an additional Boolean DB field to keep track * of the incomplete entry. * - * @author Sören Bernstein + * @author Sören Bernstein */ public class IncompleteDateParameter extends DateParameter { diff --git a/ccm-core/src/com/arsdigita/categorization/CategorizationConfig.java b/ccm-core/src/com/arsdigita/categorization/CategorizationConfig.java index 9a1ddddda..1512dc548 100644 --- a/ccm-core/src/com/arsdigita/categorization/CategorizationConfig.java +++ b/ccm-core/src/com/arsdigita/categorization/CategorizationConfig.java @@ -27,7 +27,7 @@ import org.apache.log4j.Logger; /** * Stores the configuration record for the Categorization functionality. * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein * @version $Id: CategorizationConfig.java 1169 2008-06-05 16:08:25Z quasimodo $ */ public final class CategorizationConfig extends AbstractConfig { diff --git a/ccm-core/src/com/arsdigita/categorization/CategoryLocalization.java b/ccm-core/src/com/arsdigita/categorization/CategoryLocalization.java index b234a5c85..fe1eee319 100644 --- a/ccm-core/src/com/arsdigita/categorization/CategoryLocalization.java +++ b/ccm-core/src/com/arsdigita/categorization/CategoryLocalization.java @@ -27,7 +27,7 @@ import java.math.BigDecimal; /** * - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein */ public class CategoryLocalization extends ACSObject { diff --git a/ccm-core/src/com/arsdigita/categorization/CategoryLocalizationCollection.java b/ccm-core/src/com/arsdigita/categorization/CategoryLocalizationCollection.java index 5c256d59c..a9292a69d 100644 --- a/ccm-core/src/com/arsdigita/categorization/CategoryLocalizationCollection.java +++ b/ccm-core/src/com/arsdigita/categorization/CategoryLocalizationCollection.java @@ -29,7 +29,7 @@ import com.arsdigita.persistence.DataCollection; * Category} and other classes. See, for example, {@link Category#getChildren()} * or {@link Category#getDescendants()}.

* - * @author Sören Bernstein (quasimodo) quasi@zes.uni-bremen.de + * @author Sören Bernstein **/ public class CategoryLocalizationCollection extends ACSObjectCollection { diff --git a/ccm-core/src/com/arsdigita/globalization/GlobalizationHelper.java b/ccm-core/src/com/arsdigita/globalization/GlobalizationHelper.java index 82cba0471..fe4766d94 100644 --- a/ccm-core/src/com/arsdigita/globalization/GlobalizationHelper.java +++ b/ccm-core/src/com/arsdigita/globalization/GlobalizationHelper.java @@ -16,7 +16,7 @@ import javax.servlet.http.HttpSession; /** * - * @author Sören Bernstein + * @author Sören Bernstein */ public class GlobalizationHelper { diff --git a/ccm-core/src/com/arsdigita/kernel/permissions/PermissionManager.java b/ccm-core/src/com/arsdigita/kernel/permissions/PermissionManager.java index 1b889d973..d6be852d4 100755 --- a/ccm-core/src/com/arsdigita/kernel/permissions/PermissionManager.java +++ b/ccm-core/src/com/arsdigita/kernel/permissions/PermissionManager.java @@ -193,6 +193,7 @@ public class PermissionManager { // to know that there is an assertion in the save() method in // the Permission class. new KernelExcursion() { + @Override public void excurse() { setEffectiveParty(Kernel.getSystemParty()); p.save(); diff --git a/ccm-core/src/com/arsdigita/persistence/DataQueryImpl.java b/ccm-core/src/com/arsdigita/persistence/DataQueryImpl.java index f8f6ec304..0e9ab0405 100755 --- a/ccm-core/src/com/arsdigita/persistence/DataQueryImpl.java +++ b/ccm-core/src/com/arsdigita/persistence/DataQueryImpl.java @@ -59,767 +59,753 @@ import org.apache.log4j.Logger; * DataQueryImpl * * @author Rafael H. Schloming <rhs@mit.edu> + * @author Sören Bernstein * @version $Id: DataQueryImpl.java 1304 2006-08-31 13:12:47Z sskracic $ */ class DataQueryImpl implements DataQuery { - private static final Logger s_log = Logger.getLogger(DataQueryImpl.class); - - private static final String s_unalias = - "com.arsdigita.persistence.DataQueryImpl.unalias"; - - private static final String s_mapAndAddPath = - "com.arsdigita.persistence.DataQueryImpl.mapAndAddPath"; - - private Map m_options = new HashMap(); - - private SQLParser getParser(String key, Reader reader, - SQLParser.Mapper mapper) { - TransactionContext ctx = m_ssn.getTransactionContext(); - SQLParser p = (SQLParser) ctx.getAttribute(key); - if (p == null) { - p = new SQLParser(reader, mapper); - ctx.setAttribute(key, p); - } else { - p.initialize(reader, mapper); - } - - return p; - } - - private Session m_ssn; - private com.redhat.persistence.Session m_pssn; - private HashMap m_bindings = new HashMap(); - - final Signature m_originalSig; - private Signature m_signature; - - final private Expression m_originalExpr; - private Expression m_expr; - - Cursor m_cursor = null; - private CompoundFilterImpl m_filter; - - private ArrayList m_orders = new ArrayList(); - - // This indicates the offset/limit sent of the query - private Integer m_offset = null; - private Integer m_limit = null; - - // This indicates the limits on the number of rows returned by the query - private int m_lowerBound = 0; - private int m_upperBound = Integer.MAX_VALUE; - - private final List m_aliases = new ArrayList(); - // used by addPath to implement addPath for paths traversing 0..n - private HashMap m_joins = new HashMap(); - - private final FilterFactory m_factory; - - DataQueryImpl(Session ssn, DataSet ds) { - this(ssn, ds.getSignature(), ds.getExpression()); - } - - DataQueryImpl(Session ssn, Signature sig, Expression expr) { - m_ssn = ssn; - m_pssn = ssn.getProtoSession(); - m_originalSig = sig; - m_originalExpr = expr; - m_factory = new FilterFactoryImpl(ssn); - reset(); - } - - Session getSession() { - return m_ssn; - } - - /** - * Returns the com.redhat.persistence type of the query. - */ - ObjectType getTypeInternal() { - return m_originalSig.getObjectType(); - } - - public CompoundType getType() { - throw new Error("not implemented"); - } - - public boolean hasProperty(String propertyName) { - Path p = unalias(Path.get(propertyName)); - return hasProperty(p); - } - - boolean hasProperty(Path p) { - return getTypeInternal().getProperty(p) != null; - } - - public void reset() { - close(); - m_cursor = null; - - clearOrder(); - clearFilter(); - m_lowerBound = 0; - m_upperBound = Integer.MAX_VALUE; - m_offset = null; - m_limit = null; - m_signature = new Signature(m_originalSig); - m_joins.clear(); - m_bindings.clear(); - - // XXX: hack for data queries with bindings that have calls to addPath - // addJoin needs to join against the static-ified version of the All. - // this is equivalent to testing if m_originalExpr instanceof All - if (this.getClass().equals(DataQueryImpl.class)) { - m_expr = new Define - (new Static(getTypeInternal().getQualifiedName(), m_bindings), - "this"); - } else { - m_expr = new Define(m_originalExpr, "this"); - } - - m_signature = new Signature(); - m_signature.addSignature(m_originalSig, Path.get("this")); - m_joins.put(null, "this"); - } - - - public boolean first() { - throw new Error("not implemented"); - } - - public boolean isEmpty() { - try { - // can not use checkCursor() because then we can't add filters - // after calls to isEmpty - if (m_cursor == null) { - return new DataSet - (m_pssn, m_signature, makeExpr()).isEmpty(); - } else { - return m_cursor.getDataSet().isEmpty(); - } - } catch (ProtoException e) { - throw PersistenceException.newInstance(e); - } - } - - - public boolean isBeforeFirst() { - checkCursor(); - return m_cursor.isBeforeFirst(); - } - - public boolean isFirst() { - checkCursor(); - return m_cursor.isFirst(); - } - - - public boolean isLast() { - throw new Error("not implemented"); - } - - - public boolean isAfterLast() { - checkCursor(); - return m_cursor.isAfterLast(); - } - - - public boolean last() { - throw new Error("not implemented"); - } - - - public boolean previous() { - throw new Error("not implemented"); - } - - public void addPath(String path) { - Path p = unalias(Path.get(path)); - addPath(p, true); - } - - private void addPath(Path path, boolean requiresFetching) { - if (m_cursor != null) { - throw new PersistenceException - ("Paths cannot be added on an active data query."); - } - - addJoin(path); - path = resolvePath(path); - if (requiresFetching) { - m_signature.addPath(path); - } else { - Assert.isTrue(m_signature.exists(path)); - } - } - - protected Path resolvePath(Path path) { - if (m_joins.size() == 0) { return path; } - - Path base = path; - for (; base != null; base = base.getParent()) { - if (m_joins.containsKey(base)) { - break; - } - } - - Path candidate = Path.add - ((String) m_joins.get(base), Path.relative(base, path)); - if (m_signature.exists(candidate)) { - return candidate; - } - return path; - } - - private void addJoin(Path path) { - List elts = new ArrayList(); - for (Path p = path; p != null; p = p.getParent()) { - elts.add(p.getName()); - } - - ObjectType type = getTypeInternal(); - Path coll = null; - Path prev = null; - boolean collectionFound = false; - for (int i = elts.size() - 1; i >= 0; i--) { - String propName = (String) elts.get(i); - Property prop = type.getProperty(propName); - type = prop.getType(); - coll = Path.add(coll, propName); - - if (prop.isCollection()) { - collectionFound = true; - String alias = coll.getPath().replace('.', '_'); - if (m_joins.containsKey(coll)) { - prev = coll; - continue; - } - - m_joins.put(coll, alias); - - Expression prevColl; - if (prev == null) { - prevColl = new Define - (Expression.valueOf(Path.add("this", coll)), "target"); - } else { - Path p = Path.add - ((String) m_joins.get(prev), - Path.relative(prev, coll)); - prevColl = new Define(Expression.valueOf(p), "target"); - } - - Expression cond = new Exists - (new com.redhat.persistence.oql.Filter - (prevColl, - new Equals - (new Variable(alias), new Variable("target")))); - - m_expr = new LeftJoin - (m_expr, - new Define(new All(type.getQualifiedName()), alias), - cond); - m_signature.addSource(type, Path.get(alias)); - - prev = coll; - } - - - if (propName.endsWith(PDL.LINK)) { - Path rel = null; - String assocName = propName.substring - (0, propName.length() - PDL.LINK.length()); - Path assoc = Path.add(coll.getParent(), assocName); - - addJoin(assoc); - Path pathThroughLink = Path.add(resolvePath(coll), assocName); - m_expr = new com.redhat.persistence.oql.Filter - (m_expr, new Equals - (Expression.valueOf(pathThroughLink), - Expression.valueOf(resolvePath(assoc)))); - } - } - } - - public Filter setFilter(String conditions) { - clearFilter(); - return addFilter(conditions); - } - - - public Filter addFilter(String conditions) { - if (m_cursor != null) { - throw new PersistenceException - ("The filter cannot be set on an active data query. " + - "Data query must be rewound."); - } - - return m_filter.addFilter(conditions); - } - - - public Filter addFilter(Filter filter) { - if (m_cursor != null) { - throw new PersistenceException - ("The filter cannot be set on an active data query. " + - "Data query must be rewound."); - } - - return m_filter.addFilter(filter); - } - - public boolean removeFilter(Filter filter) { - if (m_cursor != null) { - throw new PersistenceException - ("The filter cannot be removed on an active data query. " + - "Data query must be rewound."); - } - - return m_filter.removeFilter(filter); - } - - public Filter addInSubqueryFilter(String propertyName, - String subqueryName) { - return addFilter(getFilterFactory().in(propertyName, subqueryName)); - } - - - public Filter addInSubqueryFilter(String propertyName, - String subQueryProperty, - String queryName) { - return addFilter - (getFilterFactory().in - (propertyName, subQueryProperty, queryName)); - } - - public Filter addNotInSubqueryFilter(String propertyName, - String subqueryName) { - return addFilter(getFilterFactory().notIn(propertyName, subqueryName)); - } - - public Filter addEqualsFilter(String attribute, Object value) { - return addFilter(getFilterFactory().equals(attribute, value)); - } - - public Filter addNotEqualsFilter(String attribute, Object value) { - return addFilter(getFilterFactory().notEquals(attribute, value)); - } - - public void clearFilter() { - if (m_cursor != null) { - throw new PersistenceException - ("Cannot clear the filter on an active data query. " + - "Data query must be rewound."); - } - m_filter = (CompoundFilterImpl) getFilterFactory().and(); - } - - public FilterFactory getFilterFactory() { - return m_factory; - } - - public void setOrder(String order) { - clearOrder(); - addOrder(order); - } - - public void addOrder(String order) { - if (m_cursor != null) { - throw new PersistenceException - ("Cannot order an active data query. " + - "Data query must be rewound."); - } - order = unalias(order); - m_orders.add(order); - } - - private int m_order = 0; - - public void addOrderWithNull(String orderOne, Object orderTwo, - boolean isAscending) { - String suffix = null; - if (isAscending) { - suffix = "asc"; - } else { - suffix = "desc"; - } - - Object secondElement = orderTwo; - if ((orderTwo != null) && (orderTwo instanceof String)) { - Path two = unalias(Path.get((String) orderTwo)); - // XXX: - if (!hasProperty(two)) { - String var = "order" + m_order++; - secondElement = ":" + var; - setParameter(var, orderTwo); - if (orderOne != null) { - Root root = getSession().getRoot(); - ObjectType typeOne = getTypeInternal().getProperty - (unalias(Path.get(orderOne))).getType(); - if (!root.getObjectType("global.String").equals - (typeOne)) { - // this means that there is going to be a type conflict - // by the DB so we prevent it here - throw new PersistenceException("type mismatch"); - } - } - } - } - - if ((orderTwo != null) && (orderTwo instanceof Date)) { - - } - - addOrder("case when (" + orderOne + " is null) then " + - secondElement + " else " + orderOne + " end " + suffix); - } - - public void clearOrder() { - m_orders.clear(); - m_order = 0; - } - - public void setParameter(String parameterName, Object value) { - m_bindings.put(parameterName, value); - } - - - public Object getParameter(String parameterName) { - return m_bindings.get(parameterName); - } - - public void setOption(String optionName, Object value) { - m_options.put(optionName, value); - } - - public Object getOption(String optionName) { - return m_options.get(optionName); - } - - - public void setRange(Integer beginIndex) { - setRange(beginIndex, null); - } - - public void setRange(Integer beginIndex, Integer endIndex) { - if (endIndex != null && endIndex.compareTo(beginIndex) <= 0) { - throw new PersistenceException - ("The beginIndex [" + beginIndex + "] must be strictly less " + - "than the endIndex [" + endIndex + "]"); - } - - m_offset = new Integer(beginIndex.intValue() - 1); - - if (endIndex != null) { - m_limit = new Integer(endIndex.intValue() - beginIndex.intValue()); - } - } - - - public Map getPropertyValues() { - throw new Error("not implemented"); - } - - - public void setReturnsUpperBound(int upperBound) { - m_upperBound = upperBound; - } - - - public void setReturnsLowerBound(int lowerBound) { - if (lowerBound > 1 || lowerBound < 0) { - throw new PersistenceException - ("The lower bound for a given query must be 0 or 1."); - } - m_lowerBound = lowerBound; - } - - public void alias(String fromPrefix, String toPrefix) { - m_aliases.add(new Alias(fromPrefix, toPrefix)); - } - - public void close() { - if (m_cursor != null) { - m_cursor.close(); - } - } - - public void rewind() { - if (m_cursor != null) { - m_cursor.rewind(); - } - } - - - public Object get(String propertyName) { - Path path = resolvePath(unalias(Path.get(propertyName))); - try { - return m_cursor.get(path); - } catch (ProtoException e) { - throw PersistenceException.newInstance(e); - } - } - - - public int getPosition() { - checkCursor(); - return (int) m_cursor.getPosition(); - } - - private class AddPathMapper implements SQLParser.Mapper { - public Path map(Path path) { - Path p = unalias(path); - // XXX: hasProperty(p) does not work because you can't - // addPath doesn't accept paths starting with - // Session.LINK_ASSOCIATION - if (getTypeInternal().getProperty(p) != null) { - addPath(p, false); - } - return resolvePath(p); - } - } - - private SQLParser.Mapper m_mapper = new AddPathMapper(); - - Path mapAndAddPath(Path p) { - return m_mapper.map(p); - } - - String mapAndAddPaths(String s) { - StringReader reader = new StringReader(s); - SQLParser p = getParser(s_mapAndAddPath, reader, m_mapper); - - try { - p.sql(); - } catch (ParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - - return p.getSQL().toString(); - } - - private Expression makeExpr() { - String[] orders = new String[m_orders.size()]; - - for (int i = m_orders.size() - 1; i >= 0; i--) { - String order = (String) m_orders.get(i); - orders[i] = mapAndAddPaths(order); - } - - Expression filter = m_filter.makeExpression(this, m_bindings); - - // can't start finalizing expr until all paths have been added - Expression expr = m_expr; - - if (filter != null) { - expr = new com.redhat.persistence.oql.Filter - (expr, filter); - } - - for (int i = orders.length - 1; i >= 0; i--) { - expr = new Sort(expr, new Static(orders[i], m_bindings)); - } - - if (m_offset != null) { - expr = new Offset(expr, new Literal(m_offset)); - } - - if (m_limit != null) { - expr = new Limit(expr, new Literal(m_limit)); - } - - return expr; - } - - private void checkCursor() { - if (m_cursor == null) { - try { - Profiler.startOp("DB"); - m_cursor = execute(m_signature, makeExpr()); - } catch (ProtoException e) { - throw PersistenceException.newInstance(e); - } finally { - Profiler.stopOp("DB"); - } - } - } - - protected Cursor execute(Signature sig, Expression expr) { - Cursor cursor = new DataSet(m_pssn, sig, expr).getCursor(); - cursor.setOptions(m_options); - return cursor; - } - - public boolean next() { - checkCursor(); - if (m_cursor.isClosed()) { - return false; - } - - int pre = getPosition(); - - boolean result; - try { - Profiler.startOp("DB"); - result = m_cursor.next(); - } catch (ProtoException e) { - throw PersistenceException.newInstance(e); - } finally { - Profiler.stopOp("DB"); - } - - if (result) { - if (getPosition() == m_upperBound) { - if (m_cursor.next()) { - throw new PersistenceException - ("cursor exceeded upper bound"); - } - } - } else { - if (pre < m_lowerBound) { - throw new PersistenceException - ("cursor failed to meet lower bound"); - } - } - - return result; - } - - public long size() { - try { - // can not use checkCursor() because then we can't add filters - // after calls to size - if (m_cursor == null) { - return new DataSet - (m_pssn, m_signature, makeExpr()).size(); - } else { - return m_cursor.getDataSet().size(); - } - } catch (ProtoException e) { - throw PersistenceException.newInstance(e); - } - } - - private class UnaliasMapper implements SQLParser.Mapper { - public Path map(Path path) { - return unalias(path); - } - } - - private SQLParser.Mapper m_unaliaser = new UnaliasMapper(); - - String unalias(String expr) { - if (expr == null) { return null; } - StringReader reader = new StringReader(expr); - SQLParser p = getParser(s_unalias, reader, m_unaliaser); - - try { - p.sql(); - } catch (ParseException e) { - s_log.warn("Could not parse SQL: " + expr); - throw new IllegalArgumentException(e.getMessage()); - } - - return p.getSQL().toString(); - } - - Path unalias(Path path) { - if (s_log.isDebugEnabled()) { - s_log.debug("External Path: " + path); - s_log.debug("Aliases: " + m_aliases.toString()); - } - - String str = path.getPath(); - - final int index = str.indexOf(".link."); - if (index != -1) { - str = str.substring(0, index) - + PDL.LINK + "." + str.substring(index + 6); - } - path = Path.get(str); - - Path result = path; - - for (Iterator it = m_aliases.iterator(); it.hasNext(); ) { - Alias alias = (Alias) it.next(); - if (alias.isMatch(path)) { - if (s_log.isDebugEnabled()) { - s_log.debug("matched " + alias); + private static final Logger s_log = Logger.getLogger(DataQueryImpl.class); + private static final String s_unalias = + "com.arsdigita.persistence.DataQueryImpl.unalias"; + private static final String s_mapAndAddPath = + "com.arsdigita.persistence.DataQueryImpl.mapAndAddPath"; + private Map m_options = new HashMap(); + + private SQLParser getParser(String key, Reader reader, + SQLParser.Mapper mapper) { + TransactionContext ctx = m_ssn.getTransactionContext(); + SQLParser p = (SQLParser) ctx.getAttribute(key); + if (p == null) { + p = new SQLParser(reader, mapper); + ctx.setAttribute(key, p); + } else { + p.initialize(reader, mapper); } - Path candidate = alias.unalias(path); - if (hasProperty(candidate)) { - result = candidate; - break; - } - if (s_log.isDebugEnabled()) { - s_log.debug("Candidate " + candidate + " doesn't exist."); - } - } else { - if (s_log.isDebugEnabled()) { - s_log.debug("didn't match " + alias); - } - } - } + return p; + } + private Session m_ssn; + private com.redhat.persistence.Session m_pssn; + private HashMap m_bindings = new HashMap(); + final Signature m_originalSig; + private Signature m_signature; + final private Expression m_originalExpr; + private Expression m_expr; + Cursor m_cursor = null; + private CompoundFilterImpl m_filter; + private ArrayList m_orders = new ArrayList(); + // This indicates the offset/limit sent of the query + private Integer m_offset = null; + private Integer m_limit = null; + // This indicates the limits on the number of rows returned by the query + private int m_lowerBound = 0; + private int m_upperBound = Integer.MAX_VALUE; + private final List m_aliases = new ArrayList(); + // used by addPath to implement addPath for paths traversing 0..n + private HashMap m_joins = new HashMap(); + private final FilterFactory m_factory; - if (s_log.isDebugEnabled()) { - s_log.debug("Internal Path: " + result); + DataQueryImpl(Session ssn, DataSet ds) { + this(ssn, ds.getSignature(), ds.getExpression()); } - return result; - } + DataQueryImpl(Session ssn, Signature sig, Expression expr) { + m_ssn = ssn; + m_pssn = ssn.getProtoSession(); + m_originalSig = sig; + m_originalExpr = expr; + m_factory = new FilterFactoryImpl(ssn); + reset(); + } - private static class Alias { + Session getSession() { + return m_ssn; + } - private Path m_from; - private Path m_to; + /** + * Returns the com.redhat.persistence type of the query. + */ + ObjectType getTypeInternal() { + return m_originalSig.getObjectType(); + } - public Alias(String from, String to) { - Assert.assertNotEmpty(from, "from"); - Assert.assertNotEmpty(to, "to"); + public CompoundType getType() { + throw new Error("not implemented"); + } - m_from = Path.get(from); - m_to = Path.get(to); - } + public boolean hasProperty(String propertyName) { + Path p = unalias(Path.get(propertyName)); + return hasProperty(p); + } - private static final boolean isWildcard(Path path) { - return path.getParent() == null && path.getName().equals("*"); - } + boolean hasProperty(Path p) { + return getTypeInternal().getProperty(p) != null; + } - public boolean isMatch(Path path) { - if (isWildcard(m_from)) { return true; } - if (m_from.getParent() == null) { return m_from.equals(path); } - while (path.getParent() != null) { - path = path.getParent(); - } - return m_from.getParent().equals(path); - } + public void reset() { + close(); + m_cursor = null; - public Path unalias(Path path) { - if (isWildcard(m_from) && isWildcard(m_to)) { - return path; - } else if (isWildcard(m_from) && !isWildcard(m_to)) { - if (m_to.getParent() != null) { - return Path.add(m_to.getParent(), path); - } else { - throw new IllegalStateException(this + " " + path); - } - } else if (!isWildcard(m_from) && isWildcard(m_to)) { - return path.getRelative(m_from); - } else { - try { - return Path.add(m_to, path.getRelative(m_from)); - } catch (RuntimeException e) { - throw new PersistenceException(this + " " + path, e); - } - } - } + clearOrder(); + clearFilter(); + m_lowerBound = 0; + m_upperBound = Integer.MAX_VALUE; + m_offset = null; + m_limit = null; + m_signature = new Signature(m_originalSig); + m_joins.clear(); + m_bindings.clear(); - public String toString() { - return m_from + " --> " + m_to; - } + // XXX: hack for data queries with bindings that have calls to addPath + // addJoin needs to join against the static-ified version of the All. + // this is equivalent to testing if m_originalExpr instanceof All + if (this.getClass().equals(DataQueryImpl.class)) { + m_expr = new Define(new Static(getTypeInternal().getQualifiedName(), m_bindings), + "this"); + } else { + m_expr = new Define(m_originalExpr, "this"); + } - } + m_signature = new Signature(); + m_signature.addSignature(m_originalSig, Path.get("this")); + m_joins.put(null, "this"); + } + @Override + public boolean first() { + throw new Error("not implemented"); + } + + @Override + public boolean isEmpty() { + try { + // can not use checkCursor() because then we can't add filters + // after calls to isEmpty + if (m_cursor == null) { + return new DataSet(m_pssn, m_signature, makeExpr()).isEmpty(); + } else { + return m_cursor.getDataSet().isEmpty(); + } + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } + } + + @Override + public boolean isBeforeFirst() { + checkCursor(); + return m_cursor.isBeforeFirst(); + } + + @Override + public boolean isFirst() { + checkCursor(); + return m_cursor.isFirst(); + } + + @Override + public boolean isLast() { + return size() == getPosition(); + } + + @Override + public boolean isAfterLast() { + checkCursor(); + return m_cursor.isAfterLast(); + } + + @Override + public boolean last() { + throw new Error("not implemented"); + } + + @Override + public boolean previous() { + checkCursor(); + if (m_cursor.isClosed()) { + return false; + } + + int pre = getPosition(); + + boolean result; + try { + Profiler.startOp("DB"); + result = m_cursor.previous(); + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } finally { + Profiler.stopOp("DB"); + } + + if (result) { + if (getPosition() == m_upperBound) { + if (m_cursor.previous()) { + throw new PersistenceException("cursor exceeded upper bound"); + } + } + } else { + if (pre < m_lowerBound) { + throw new PersistenceException("cursor failed to meet lower bound"); + } + } + + return result; + } + + public void addPath(String path) { + Path p = unalias(Path.get(path)); + addPath(p, true); + } + + private void addPath(Path path, boolean requiresFetching) { + if (m_cursor != null) { + throw new PersistenceException("Paths cannot be added on an active data query."); + } + + addJoin(path); + path = resolvePath(path); + if (requiresFetching) { + m_signature.addPath(path); + } else { + Assert.isTrue(m_signature.exists(path)); + } + } + + protected Path resolvePath(Path path) { + if (m_joins.size() == 0) { + return path; + } + + Path base = path; + for (; base != null; base = base.getParent()) { + if (m_joins.containsKey(base)) { + break; + } + } + + Path candidate = Path.add((String) m_joins.get(base), Path.relative(base, path)); + if (m_signature.exists(candidate)) { + return candidate; + } + return path; + } + + private void addJoin(Path path) { + List elts = new ArrayList(); + for (Path p = path; p != null; p = p.getParent()) { + elts.add(p.getName()); + } + + ObjectType type = getTypeInternal(); + Path coll = null; + Path prev = null; + boolean collectionFound = false; + for (int i = elts.size() - 1; i >= 0; i--) { + String propName = (String) elts.get(i); + Property prop = type.getProperty(propName); + type = prop.getType(); + coll = Path.add(coll, propName); + + if (prop.isCollection()) { + collectionFound = true; + String alias = coll.getPath().replace('.', '_'); + if (m_joins.containsKey(coll)) { + prev = coll; + continue; + } + + m_joins.put(coll, alias); + + Expression prevColl; + if (prev == null) { + prevColl = new Define(Expression.valueOf(Path.add("this", coll)), "target"); + } else { + Path p = Path.add((String) m_joins.get(prev), + Path.relative(prev, coll)); + prevColl = new Define(Expression.valueOf(p), "target"); + } + + Expression cond = new Exists(new com.redhat.persistence.oql.Filter(prevColl, + new Equals(new Variable(alias), new Variable("target")))); + + m_expr = new LeftJoin(m_expr, + new Define(new All(type.getQualifiedName()), alias), + cond); + m_signature.addSource(type, Path.get(alias)); + + prev = coll; + } + + + if (propName.endsWith(PDL.LINK)) { + Path rel = null; + String assocName = propName.substring(0, propName.length() - PDL.LINK.length()); + Path assoc = Path.add(coll.getParent(), assocName); + + addJoin(assoc); + Path pathThroughLink = Path.add(resolvePath(coll), assocName); + m_expr = new com.redhat.persistence.oql.Filter(m_expr, new Equals(Expression.valueOf(pathThroughLink), + Expression.valueOf(resolvePath(assoc)))); + } + } + } + + public Filter setFilter(String conditions) { + clearFilter(); + return addFilter(conditions); + } + + public Filter addFilter(String conditions) { + if (m_cursor != null) { + throw new PersistenceException("The filter cannot be set on an active data query. " + + "Data query must be rewound."); + } + + return m_filter.addFilter(conditions); + } + + public Filter addFilter(Filter filter) { + if (m_cursor != null) { + throw new PersistenceException("The filter cannot be set on an active data query. " + + "Data query must be rewound."); + } + + return m_filter.addFilter(filter); + } + + public boolean removeFilter(Filter filter) { + if (m_cursor != null) { + throw new PersistenceException("The filter cannot be removed on an active data query. " + + "Data query must be rewound."); + } + + return m_filter.removeFilter(filter); + } + + public Filter addInSubqueryFilter(String propertyName, + String subqueryName) { + return addFilter(getFilterFactory().in(propertyName, subqueryName)); + } + + public Filter addInSubqueryFilter(String propertyName, + String subQueryProperty, + String queryName) { + return addFilter(getFilterFactory().in(propertyName, subQueryProperty, queryName)); + } + + public Filter addNotInSubqueryFilter(String propertyName, + String subqueryName) { + return addFilter(getFilterFactory().notIn(propertyName, subqueryName)); + } + + public Filter addEqualsFilter(String attribute, Object value) { + return addFilter(getFilterFactory().equals(attribute, value)); + } + + public Filter addNotEqualsFilter(String attribute, Object value) { + return addFilter(getFilterFactory().notEquals(attribute, value)); + } + + public void clearFilter() { + if (m_cursor != null) { + throw new PersistenceException("Cannot clear the filter on an active data query. " + + "Data query must be rewound."); + } + m_filter = (CompoundFilterImpl) getFilterFactory().and(); + } + + public FilterFactory getFilterFactory() { + return m_factory; + } + + public void setOrder(String order) { + clearOrder(); + addOrder(order); + } + + public void addOrder(String order) { + if (m_cursor != null) { + throw new PersistenceException("Cannot order an active data query. " + + "Data query must be rewound."); + } + order = unalias(order); + m_orders.add(order); + } + private int m_order = 0; + + public void addOrderWithNull(String orderOne, Object orderTwo, + boolean isAscending) { + String suffix = null; + if (isAscending) { + suffix = "asc"; + } else { + suffix = "desc"; + } + + Object secondElement = orderTwo; + if ((orderTwo != null) && (orderTwo instanceof String)) { + Path two = unalias(Path.get((String) orderTwo)); + // XXX: + if (!hasProperty(two)) { + String var = "order" + m_order++; + secondElement = ":" + var; + setParameter(var, orderTwo); + if (orderOne != null) { + Root root = getSession().getRoot(); + ObjectType typeOne = getTypeInternal().getProperty(unalias(Path.get(orderOne))).getType(); + if (!root.getObjectType("global.String").equals(typeOne)) { + // this means that there is going to be a type conflict + // by the DB so we prevent it here + throw new PersistenceException("type mismatch"); + } + } + } + } + + if ((orderTwo != null) && (orderTwo instanceof Date)) { + } + + addOrder("case when (" + orderOne + " is null) then " + + secondElement + " else " + orderOne + " end " + suffix); + } + + public void clearOrder() { + m_orders.clear(); + m_order = 0; + } + + public void setParameter(String parameterName, Object value) { + m_bindings.put(parameterName, value); + } + + public Object getParameter(String parameterName) { + return m_bindings.get(parameterName); + } + + public void setOption(String optionName, Object value) { + m_options.put(optionName, value); + } + + public Object getOption(String optionName) { + return m_options.get(optionName); + } + + public void setRange(Integer beginIndex) { + setRange(beginIndex, null); + } + + public void setRange(Integer beginIndex, Integer endIndex) { + if (endIndex != null && endIndex.compareTo(beginIndex) <= 0) { + throw new PersistenceException("The beginIndex [" + beginIndex + "] must be strictly less " + + "than the endIndex [" + endIndex + "]"); + } + + m_offset = new Integer(beginIndex.intValue() - 1); + + if (endIndex != null) { + m_limit = new Integer(endIndex.intValue() - beginIndex.intValue()); + } + } + + public Map getPropertyValues() { + throw new Error("not implemented"); + } + + public void setReturnsUpperBound(int upperBound) { + m_upperBound = upperBound; + } + + public void setReturnsLowerBound(int lowerBound) { + if (lowerBound > 1 || lowerBound < 0) { + throw new PersistenceException("The lower bound for a given query must be 0 or 1."); + } + m_lowerBound = lowerBound; + } + + public void alias(String fromPrefix, String toPrefix) { + m_aliases.add(new Alias(fromPrefix, toPrefix)); + } + + public void close() { + if (m_cursor != null) { + m_cursor.close(); + } + } + + public void rewind() { + if (m_cursor != null) { + m_cursor.rewind(); + } + } + + public Object get(String propertyName) { + Path path = resolvePath(unalias(Path.get(propertyName))); + try { + return m_cursor.get(path); + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } + } + + public int getPosition() { + checkCursor(); + return (int) m_cursor.getPosition(); + } + + private class AddPathMapper implements SQLParser.Mapper { + + public Path map(Path path) { + Path p = unalias(path); + // XXX: hasProperty(p) does not work because you can't + // addPath doesn't accept paths starting with + // Session.LINK_ASSOCIATION + if (getTypeInternal().getProperty(p) != null) { + addPath(p, false); + } + return resolvePath(p); + } + } + private SQLParser.Mapper m_mapper = new AddPathMapper(); + + Path mapAndAddPath(Path p) { + return m_mapper.map(p); + } + + String mapAndAddPaths(String s) { + StringReader reader = new StringReader(s); + SQLParser p = getParser(s_mapAndAddPath, reader, m_mapper); + + try { + p.sql(); + } catch (ParseException e) { + throw new IllegalArgumentException(e.getMessage()); + } + + return p.getSQL().toString(); + } + + private Expression makeExpr() { + String[] orders = new String[m_orders.size()]; + + for (int i = m_orders.size() - 1; i >= 0; i--) { + String order = (String) m_orders.get(i); + orders[i] = mapAndAddPaths(order); + } + + Expression filter = m_filter.makeExpression(this, m_bindings); + + // can't start finalizing expr until all paths have been added + Expression expr = m_expr; + + if (filter != null) { + expr = new com.redhat.persistence.oql.Filter(expr, filter); + } + + for (int i = orders.length - 1; i >= 0; i--) { + expr = new Sort(expr, new Static(orders[i], m_bindings)); + } + + if (m_offset != null) { + expr = new Offset(expr, new Literal(m_offset)); + } + + if (m_limit != null) { + expr = new Limit(expr, new Literal(m_limit)); + } + + return expr; + } + + private void checkCursor() { + if (m_cursor == null) { + try { + Profiler.startOp("DB"); + m_cursor = execute(m_signature, makeExpr()); + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } finally { + Profiler.stopOp("DB"); + } + } + } + + protected Cursor execute(Signature sig, Expression expr) { + Cursor cursor = new DataSet(m_pssn, sig, expr).getCursor(); + cursor.setOptions(m_options); + return cursor; + } + + public boolean next() { + checkCursor(); + if (m_cursor.isClosed()) { + return false; + } + + int pre = getPosition(); + + boolean result; + try { + Profiler.startOp("DB"); + result = m_cursor.next(); + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } finally { + Profiler.stopOp("DB"); + } + + if (result) { + if (getPosition() == m_upperBound) { + if (m_cursor.next()) { + throw new PersistenceException("cursor exceeded upper bound"); + } + } + } else { + if (pre < m_lowerBound) { + throw new PersistenceException("cursor failed to meet lower bound"); + } + } + + return result; + } + + public long size() { + try { + // can not use checkCursor() because then we can't add filters + // after calls to size + if (m_cursor == null) { + return new DataSet(m_pssn, m_signature, makeExpr()).size(); + } else { + return m_cursor.getDataSet().size(); + } + } catch (ProtoException e) { + throw PersistenceException.newInstance(e); + } + } + + private class UnaliasMapper implements SQLParser.Mapper { + + public Path map(Path path) { + return unalias(path); + } + } + private SQLParser.Mapper m_unaliaser = new UnaliasMapper(); + + String unalias(String expr) { + if (expr == null) { + return null; + } + StringReader reader = new StringReader(expr); + SQLParser p = getParser(s_unalias, reader, m_unaliaser); + + try { + p.sql(); + } catch (ParseException e) { + s_log.warn("Could not parse SQL: " + expr); + throw new IllegalArgumentException(e.getMessage()); + } + + return p.getSQL().toString(); + } + + Path unalias(Path path) { + if (s_log.isDebugEnabled()) { + s_log.debug("External Path: " + path); + s_log.debug("Aliases: " + m_aliases.toString()); + } + + String str = path.getPath(); + + final int index = str.indexOf(".link."); + if (index != -1) { + str = str.substring(0, index) + + PDL.LINK + "." + str.substring(index + 6); + } + path = Path.get(str); + + Path result = path; + + for (Iterator it = m_aliases.iterator(); it.hasNext();) { + Alias alias = (Alias) it.next(); + if (alias.isMatch(path)) { + if (s_log.isDebugEnabled()) { + s_log.debug("matched " + alias); + } + Path candidate = alias.unalias(path); + if (hasProperty(candidate)) { + result = candidate; + break; + } + + if (s_log.isDebugEnabled()) { + s_log.debug("Candidate " + candidate + " doesn't exist."); + } + } else { + if (s_log.isDebugEnabled()) { + s_log.debug("didn't match " + alias); + } + } + } + + if (s_log.isDebugEnabled()) { + s_log.debug("Internal Path: " + result); + } + + return result; + } + + private static class Alias { + + private Path m_from; + private Path m_to; + + public Alias(String from, String to) { + Assert.assertNotEmpty(from, "from"); + Assert.assertNotEmpty(to, "to"); + + m_from = Path.get(from); + m_to = Path.get(to); + } + + private static final boolean isWildcard(Path path) { + return path.getParent() == null && path.getName().equals("*"); + } + + public boolean isMatch(Path path) { + if (isWildcard(m_from)) { + return true; + } + if (m_from.getParent() == null) { + return m_from.equals(path); + } + while (path.getParent() != null) { + path = path.getParent(); + } + return m_from.getParent().equals(path); + } + + public Path unalias(Path path) { + if (isWildcard(m_from) && isWildcard(m_to)) { + return path; + } else if (isWildcard(m_from) && !isWildcard(m_to)) { + if (m_to.getParent() != null) { + return Path.add(m_to.getParent(), path); + } else { + throw new IllegalStateException(this + " " + path); + } + } else if (!isWildcard(m_from) && isWildcard(m_to)) { + return path.getRelative(m_from); + } else { + try { + return Path.add(m_to, path.getRelative(m_from)); + } catch (RuntimeException e) { + throw new PersistenceException(this + " " + path, e); + } + } + } + + public String toString() { + return m_from + " --> " + m_to; + } + } } diff --git a/ccm-core/src/com/arsdigita/search/ui/filters/DateRangeFilterWidget.java b/ccm-core/src/com/arsdigita/search/ui/filters/DateRangeFilterWidget.java index 049f03fb2..578d12e16 100755 --- a/ccm-core/src/com/arsdigita/search/ui/filters/DateRangeFilterWidget.java +++ b/ccm-core/src/com/arsdigita/search/ui/filters/DateRangeFilterWidget.java @@ -42,7 +42,7 @@ import java.util.Locale; * Effect will be visible in Mandalay beginning with r163. * * @author unknown... - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class DateRangeFilterWidget extends FilterWidget { diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminConstants.java b/ccm-core/src/com/arsdigita/ui/admin/AdminConstants.java index b45f653ee..c2d4649d9 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminConstants.java +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminConstants.java @@ -56,15 +56,15 @@ interface AdminConstants { /** Administration main tab names. */ Label USER_TAB_TITLE = new Label - (new GlobalizedMessage("ui.admin.tab.user.title", + (new GlobalizedMessage("ui.admin.tab.user", BUNDLE_NAME)); Label GROUP_TAB_TITLE = new Label - (new GlobalizedMessage("ui.admin.tab.group.title", + (new GlobalizedMessage("ui.admin.tab.group", BUNDLE_NAME)); Label APPLICATIONS_TAB_TITLE = new Label - (new GlobalizedMessage("ui.admin.tab.applications.title", + (new GlobalizedMessage("ui.admin.tab.applications", BUNDLE_NAME)); Label INFO_TAB_TITLE = new Label(new GlobalizedMessage("ui.admin.tab.info.title", BUNDLE_NAME)); diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties index 0070faa6b..e7f4defc8 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties @@ -34,13 +34,13 @@ ui.admin.nav.logout=Log out ui.admin.nav.workspace=Workspace ui.admin.searchAndList.submit=Search ui.admin.searchAndList.submitAgain=Search Again -ui.admin.tab.group.title=Groups +ui.admin.tab.group=Groups ui.admin.tab.user.browse=Browse ui.admin.tab.user.createuser=Create new user ui.admin.tab.user.navbartitle=User Administration ui.admin.tab.user.search=Search ui.admin.tab.user.summary=Summary -ui.admin.tab.user.title=Users +ui.admin.tab.user=Users ui.admin.user.action.continue=Continue ui.admin.user.action.delete.failed.header=Unable to delete user ui.admin.user.action.header=Actions @@ -90,7 +90,7 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Confirm password: ui.admin.user.userpasswordform.passwordlabel=Password: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Change -ui.admin.tab.applications.title=Applications +ui.admin.tab.applications=Applications ui.admin.applications.tree.heading=Applications ui.admin.applications.url.validation.not_blank=The URL of an application instance can is mandatory. ui.admin.applications.url.valiation.minmaxlength=The length of an URL of an application instance must be between 1 and 100 characters. diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties index f6b90274a..ba07a1a3b 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties @@ -34,13 +34,13 @@ ui.admin.nav.logout=Abmelden ui.admin.nav.workspace=Workspace ui.admin.searchAndList.submit=Suchen ui.admin.searchAndList.submitAgain=Erneut suchen -ui.admin.tab.group.title=Gruppen +ui.admin.tab.group=Gruppen ui.admin.tab.user.browse=Bl\u00e4ttern ui.admin.tab.user.createuser=Neuen Benutzer erstellen ui.admin.tab.user.navbartitle=Benutzerverwaltung ui.admin.tab.user.search=Suche ui.admin.tab.user.summary=Zusammenfassung -ui.admin.tab.user.title=Benutzer +ui.admin.tab.user=Benutzer ui.admin.user.action.continue=Fortfahren ui.admin.user.action.delete.failed.header=Benutzer kann nicht gel\u00f6scht werden ui.admin.user.action.header=Aktionen @@ -90,7 +90,7 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Passwort best\u00e4tigen\: ui.admin.user.userpasswordform.passwordlabel=Passwort\: ui.admin.user.userpasswordform.question=Frage\: ui.admin.user.userpasswordform.submit=\u00c4ndern -ui.admin.tab.applications.title=Applikationen +ui.admin.tab.applications=Applikationen ui.admin.applications.tree.heading=Applikationen ui.admin.applications.url.validation.not_blank=Die Angabe einer URL ist erforderlich ui.admin.applications.url.valiation.minmaxlength=Die URL einer Applikations-Instanz muss zwischen einem und 100 Zeichen lang sein diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties index 556360826..406fc0066 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties @@ -34,13 +34,13 @@ ui.admin.nav.logout=Log out ui.admin.nav.workspace=Workspace ui.admin.searchAndList.submit=Search ui.admin.searchAndList.submitAgain=Search Again -ui.admin.tab.group.title=Groups +ui.admin.tab.group=Groups ui.admin.tab.user.browse=Browse ui.admin.tab.user.createuser=Create new user ui.admin.tab.user.navbartitle=User Administration ui.admin.tab.user.search=Search ui.admin.tab.user.summary=Summary -ui.admin.tab.user.title=Users +ui.admin.tab.user=Users ui.admin.user.action.continue=Continue ui.admin.user.action.delete.failed.header=Unable to delete user ui.admin.user.action.header=Actions @@ -90,7 +90,7 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Confirm password: ui.admin.user.userpasswordform.passwordlabel=Password: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Change -ui.admin.tab.applications.title=Applications +ui.admin.tab.applications=Applications ui.admin.applications.tree.heading=Applications ui.admin.applications.url.validation.not_blank= ui.admin.applications.url.valiation.minmaxlength= diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties index 3a3769d30..b4188f3c5 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -25,13 +25,13 @@ ui.admin.nav.logout=D\u00e9connexion ui.admin.nav.workspace=Espace de travail ui.admin.searchAndList.submit=Rechercher ui.admin.searchAndList.submitAgain=Rechercher suivant -ui.admin.tab.group.title=Groupe +ui.admin.tab.group=Groupe ui.admin.tab.user.browse=Parcourir ui.admin.tab.user.createuser=Cr\u00e9er un nouvel utilisateur ui.admin.tab.user.navbartitle=Gestion de l'utilisateur ui.admin.tab.user.search=Rechercher ui.admin.tab.user.summary=Table des mati\u00e8res -ui.admin.tab.user.title=Utilisateurs +ui.admin.tab.user=Utilisateurs ui.admin.user.action.continue=Continuer ui.admin.user.action.delete.failed.header=Impossible de supprimer l'utiisateur ui.admin.user.action.header=Actions @@ -76,7 +76,7 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Confirmer le mot de passe: ui.admin.user.userpasswordform.passwordlabel=Mot de passe: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Changer -ui.admin.tab.applications.title= +ui.admin.tab.applications= ui.admin.applications.tree.heading= ui.admin.applications.url.validation.not_blank= ui.admin.applications.url.valiation.minmaxlength= diff --git a/ccm-core/src/com/arsdigita/util/SystemInformation.java b/ccm-core/src/com/arsdigita/util/SystemInformation.java index 6199cf39a..b73560763 100644 --- a/ccm-core/src/com/arsdigita/util/SystemInformation.java +++ b/ccm-core/src/com/arsdigita/util/SystemInformation.java @@ -11,7 +11,7 @@ import java.util.Set; /** * - * @author Sören Bernstein (quasimodo) + * @author Sören Bernstein */ public class SystemInformation implements Lockable { diff --git a/ccm-core/src/com/arsdigita/webdevsupport/ui/ConfigParameterList.java b/ccm-core/src/com/arsdigita/webdevsupport/ui/ConfigParameterList.java index 614de5a26..c1c686e03 100755 --- a/ccm-core/src/com/arsdigita/webdevsupport/ui/ConfigParameterList.java +++ b/ccm-core/src/com/arsdigita/webdevsupport/ui/ConfigParameterList.java @@ -56,6 +56,7 @@ public class ConfigParameterList extends SimpleContainer { XML_NS); } + @Override public void generateXML(PageState state, Element parent) { Element content = generateParent(parent); @@ -117,6 +118,7 @@ public class ConfigParameterList extends SimpleContainer { p.addAttribute("isRequired", XML.format(new Boolean(param.isRequired()))); param.write(new ParameterWriter() { + @Override public void write(Parameter param, String value) { if (value != null) { p.addAttribute("value", value); @@ -152,6 +154,7 @@ public class ConfigParameterList extends SimpleContainer { m_contexts = contexts; } + @Override public void startElement(String uri, String localName, String qn, Attributes attrs) { if (localName.equals("config")) { diff --git a/ccm-core/src/com/arsdigita/xml/formatters/DateFormatter.java b/ccm-core/src/com/arsdigita/xml/formatters/DateFormatter.java index 5718663e3..304cae03b 100755 --- a/ccm-core/src/com/arsdigita/xml/formatters/DateFormatter.java +++ b/ccm-core/src/com/arsdigita/xml/formatters/DateFormatter.java @@ -30,7 +30,7 @@ import java.text.DateFormat; * is ommitted. * * @author unkknown - * @author Sören Bernstein + * @author Sören Bernstein */ public class DateFormatter implements Formatter { diff --git a/ccm-core/src/com/arsdigita/xml/formatters/DateTimeFormatter.java b/ccm-core/src/com/arsdigita/xml/formatters/DateTimeFormatter.java index 4b71ecb80..528f90db3 100755 --- a/ccm-core/src/com/arsdigita/xml/formatters/DateTimeFormatter.java +++ b/ccm-core/src/com/arsdigita/xml/formatters/DateTimeFormatter.java @@ -29,7 +29,7 @@ import java.text.DateFormat; * 'medium' format and the time in 'short' format. * * @author unknown - * @author Sören Bernstein + * @author Sören Bernstein */ public class DateTimeFormatter implements Formatter { diff --git a/ccm-core/src/com/arsdigita/xml/formatters/TimeFormatter.java b/ccm-core/src/com/arsdigita/xml/formatters/TimeFormatter.java index 9db227c11..4c377029d 100755 --- a/ccm-core/src/com/arsdigita/xml/formatters/TimeFormatter.java +++ b/ccm-core/src/com/arsdigita/xml/formatters/TimeFormatter.java @@ -30,7 +30,7 @@ import java.text.DateFormat; * is ommitted. * * @author unknown - * @author Sören Bernstein + * @author Sören Bernstein */ public class TimeFormatter implements Formatter { diff --git a/ccm-core/src/com/redhat/persistence/Cursor.java b/ccm-core/src/com/redhat/persistence/Cursor.java index 7c2fb0f86..6faa1235e 100755 --- a/ccm-core/src/com/redhat/persistence/Cursor.java +++ b/ccm-core/src/com/redhat/persistence/Cursor.java @@ -27,172 +27,213 @@ import org.apache.log4j.Logger; * Cursor * * @author rhs@mit.edu + * @author Sören Bernstein * @version $Id: Cursor.java 1393 2006-11-28 09:12:32Z sskracic $ - **/ - + * + */ public class Cursor { - private static final Logger s_log = Logger.getLogger(Cursor.class); + private static final Logger s_log = Logger.getLogger(Cursor.class); + final private DataSet m_ds; + private RecordSet m_rs = null; + private Map m_values = null; + private long m_position = 0; + private boolean m_closed = false; + private Map m_options = new HashMap(); - final private DataSet m_ds; + protected Cursor(DataSet ds) { + m_ds = ds; + } - private RecordSet m_rs = null; - private Map m_values = null; - private long m_position = 0; - private boolean m_closed = false; - private Map m_options = new HashMap(); + public void setOptions(Map options) { + m_options.clear(); + m_options.putAll(options); + } - protected Cursor(DataSet ds) { - m_ds = ds; - } + public DataSet getDataSet() { + return m_ds; + } - public void setOptions(Map options) { - m_options.clear(); - m_options.putAll(options); - } + public Session getSession() { + return m_ds.getSession(); + } - public DataSet getDataSet() { - return m_ds; - } + public boolean isClosed() { + return m_closed; + } - public Session getSession() { - return m_ds.getSession(); - } + private Object getInternal(Path path) { + if (m_values.containsKey(path)) { + return m_values.get(path); + } else { + Object o = getInternal(path.getParent()); + if (o == null) { + return null; + } + return getSession().get(o, Path.get(path.getName())); + } + } - public boolean isClosed() { - return m_closed; - } + public Object get(Path path) { + if (m_closed) { + throw new ClosedException(this); + } - private Object getInternal(Path path) { - if (m_values.containsKey(path)) { - return m_values.get(path); - } else { - Object o = getInternal(path.getParent()); - if (o == null) { return null; } - return getSession().get(o, Path.get(path.getName())); - } - } + if (m_position <= 0) { + throw new NoRowException(this); + } - public Object get(Path path) { - if (m_closed) { - throw new ClosedException(this); - } + if (!m_rs.isFetched(path)) { + if (s_log.isDebugEnabled()) { + s_log.debug("path " + path + " is not fetched" + + " in signature " + m_ds.getSignature()); + } + throw new NotFetchedException(this, path); + } - if (m_position <= 0) { - throw new NoRowException(this); - } + return getInternal(path); + } - if (!m_rs.isFetched(path)) { - if (s_log.isDebugEnabled()) { - s_log.debug("path " + path + " is not fetched" - + " in signature " + m_ds.getSignature()); - } - throw new NotFetchedException(this, path); - } + public Object get(String path) { + if (m_closed) { + throw new ClosedException(this); + } - return getInternal(path); - } + return get(Path.get(path)); + } - public Object get(String path) { - if (m_closed) { - throw new ClosedException(this); - } + public Object get() { + if (m_closed) { + throw new ClosedException(this); + } - return get(Path.get(path)); - } + return m_values.get(null); + } - public Object get() { - if (m_closed) { - throw new ClosedException(this); - } + public boolean next() { + if (m_closed) { + throw new ClosedException(this); + } - return m_values.get(null); - } + if (m_position == -1) { + return false; + } - public boolean next() { - if (m_closed) { - throw new ClosedException(this); - } + if (m_rs == null) { + getSession().flush(); + m_rs = execute(); + } - if (m_position == -1) { - return false; - } + if (m_rs.next()) { + m_values = m_rs.load(getSession()); - if (m_rs == null) { - getSession().flush(); - m_rs = execute(); - } + m_position++; + return true; + } else { + m_position = -1; + free(); + return false; + } + } - if (m_rs.next()) { - m_values = m_rs.load(getSession()); + protected RecordSet execute() { + return getSession().getEngine().execute(m_ds.getSignature(), + m_ds.getExpression(), + m_options); + } - m_position++; - return true; - } else { - m_position = -1; - free(); - return false; - } - } + public boolean isBeforeFirst() { + if (m_closed) { + throw new ClosedException(this); + } - protected RecordSet execute() { - return getSession().getEngine().execute(m_ds.getSignature(), - m_ds.getExpression(), - m_options); - } + return m_position == 0; + } - public boolean isBeforeFirst() { - if (m_closed) { - throw new ClosedException(this); - } + public boolean isFirst() { + if (m_closed) { + throw new ClosedException(this); + } - return m_position == 0; - } + return m_position == 1; + } - public boolean isFirst() { - if (m_closed) { - throw new ClosedException(this); - } + public boolean isAfterLast() { + if (m_closed) { + throw new ClosedException(this); + } - return m_position == 1; - } + return m_position == -1; + } - public boolean isAfterLast() { - if (m_closed) { - throw new ClosedException(this); - } + public long getPosition() { + if (m_closed) { + throw new ClosedException(this); + } - return m_position == -1; - } + if (m_position > 0) { + return m_position; + } else { + return 0; + } + } - public long getPosition() { - if (m_closed) { - throw new ClosedException(this); - } + public void rewind() { + close(); + m_position = 0; + m_closed = false; + } - if (m_position > 0) { - return m_position; - } else { - return 0; - } - } + private void free() { + if (m_rs != null) { + m_rs.close(); + m_rs = null; + } + } - public void rewind() { - close(); - m_position = 0; - m_closed = false; - } + public void close() { + free(); + m_closed = true; + } - private void free() { - if (m_rs != null) { - m_rs.close(); - m_rs = null; - } - } + /** + * An expensive previous method, which will iterate the list from the + * beginning to the previous to current position. Sadly, the more efficient + * way is not possible with this persistent layer because it will only work + * with ResultSets in FORWARD_ONLY mode. + * + * @return boolean true, if there is a previous element, false otherwise + */ + public boolean previous() { + if (m_closed) { + throw new ClosedException(this); + } - public void close() { - free(); - m_closed = true; - } + // Make sure, we don't go before the first entry (position == 1) + if (m_position <= 1) { + return false; + } + // If there isn't a result set, get a new one + if (m_rs == null) { + getSession().flush(); + m_rs = execute(); + } + + // Have to go the long way because the persistent layer can only operate + // with ResultSet in FORWARD_ONLY mode + long newPosition = getPosition() - 1; + + // Reset the list, aka rewind and get a new resultset + rewind(); + getSession().flush(); + m_rs = execute(); + + // Iterate to new position + while (m_position < newPosition) { + next(); + } + + return true; + } }