diff --git a/ccm-cms-assets-imagestep/.svnignore b/ccm-cms-assets-imagestep/.svnignore
new file mode 100755
index 000000000..378eac25d
--- /dev/null
+++ b/ccm-cms-assets-imagestep/.svnignore
@@ -0,0 +1 @@
+build
diff --git a/ccm-cms-assets-imagestep/README b/ccm-cms-assets-imagestep/README
new file mode 100755
index 000000000..e69de29bb
diff --git a/ccm-cms-assets-imagestep/application.xml b/ccm-cms-assets-imagestep/application.xml
new file mode 100755
index 000000000..1668a023f
--- /dev/null
+++ b/ccm-cms-assets-imagestep/application.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ UI step for attaching an image to article (or other content types).
+
+
diff --git a/ccm-cms-assets-imagestep/pdl/com/arsdigita/cms/contentassets/ItemImageAttachment.pdl b/ccm-cms-assets-imagestep/pdl/com/arsdigita/cms/contentassets/ItemImageAttachment.pdl
new file mode 100755
index 000000000..4f7b4c643
--- /dev/null
+++ b/ccm-cms-assets-imagestep/pdl/com/arsdigita/cms/contentassets/ItemImageAttachment.pdl
@@ -0,0 +1,27 @@
+model com.arsdigita.cms.contentassets;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ReusableImageAsset;
+import com.arsdigita.cms.contenttypes.Link;
+import com.arsdigita.kernel.ACSObject;
+
+object type ItemImageAttachment extends ACSObject {
+ String[0..1] useContext = cms_item_image_attachment.use_context VARCHAR( 100 );
+ String[0..1] caption = cms_item_image_attachment.caption VARCHAR( 100 );
+ String[0..1] title = cms_item_image_attachment.title VARCHAR( 200 );
+ String[0..1] description = cms_item_image_attachment.description VARCHAR( 4000 );
+ component Link[0..1] imageLink = join cms_item_image_attachment.link_id to cms_links.link_id;
+
+ composite ReusableImageAsset[0..1] image
+ = join cms_item_image_attachment.image_id to cms_images.image_id;
+
+ reference key (cms_item_image_attachment.attachment_id);
+}
+
+association {
+ component ItemImageAttachment[0..n] imageAttachments
+ = join cms_items.item_id to cms_item_image_attachment.item_id;
+
+ composite ContentItem[0..1] item
+ = join cms_item_image_attachment.item_id to cms_items.item_id;
+}
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se-create.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se-create.sql
new file mode 100755
index 000000000..c0dc9966a
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se-create.sql
@@ -0,0 +1,2 @@
+@ ddl/oracle-se/create.sql
+@ ddl/oracle-se/deferred.sql
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
new file mode 100755
index 000000000..a300c3e9a
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
@@ -0,0 +1,23 @@
+--
+-- Copyright (C) 2005 Runtime Collective Ltd. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+-- $Id: alter-table-authoring_steps.sql 285 2005-02-22 00:29:02Z sskracic $
+-- $DateTime: 2004/08/17 23:15:09 $
+
+alter table cms_item_image_attachment add (title VARCHAR(200));
+alter table cms_item_image_attachment add (description VARCHAR(4000));
+
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.5.0-6.5.1/add_link_column.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.5.0-6.5.1/add_link_column.sql
new file mode 100644
index 000000000..89328429b
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/oracle-se/upgrade/6.5.0-6.5.1/add_link_column.sql
@@ -0,0 +1,25 @@
+--
+-- Copyright (C) 2005 Chris Gilbert. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+
+alter table cms_item_image_attachment add (link_id NUMBER);
+
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_lin_id_f_eeymm foreign key (link_id)
+ references cms_links(link_id);
+
+
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres-create.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres-create.sql
new file mode 100755
index 000000000..38209a696
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres-create.sql
@@ -0,0 +1,4 @@
+begin;
+\i ddl/postgres/create.sql
+\i ddl/postgres/deferred.sql
+end;
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
new file mode 100755
index 000000000..57ee78599
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
@@ -0,0 +1,23 @@
+--
+-- Copyright (C) 2005 Runtime Collective Ltd. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+-- $Id: alter-table-authoring_steps.sql 285 2005-02-22 00:29:02Z sskracic $
+-- $DateTime: 2004/08/17 23:15:09 $
+
+alter table cms_item_image_attachment add title VARCHAR(200);
+alter table cms_item_image_attachment add description VARCHAR(4000);
+
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.5.0-6.5.1/add_link_column.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.5.0-6.5.1/add_link_column.sql
new file mode 100644
index 000000000..876cd42aa
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/postgres/upgrade/6.5.0-6.5.1/add_link_column.sql
@@ -0,0 +1,25 @@
+--
+-- Copyright (C) 2005 Chris Gilbert. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+
+alter table cms_item_image_attachment add link_id INTEGER;
+
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_lin_id_f_eeymm foreign key (link_id)
+ references cms_links(link_id);
+
+
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-1.0.0-2.0.0.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-1.0.0-2.0.0.sql
new file mode 100755
index 000000000..a113f3dee
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-1.0.0-2.0.0.sql
@@ -0,0 +1,51 @@
+
+PROMPT ImageStep 1.0.0 -> 2.0.0 Upgrade Script (Oracle)
+
+update acs_objects set
+object_type = 'com.arsdigita.cms.ReusableImageAsset',
+default_domain_class = 'com.arsdigita.cms.ReusableImageAsset'
+where object_type = 'com.arsdigita.cms.contenttypes.AttachableImage';
+
+drop table cms_attachable_images;
+
+@@ ../ddl/postgres/table-cms_item_image_attachment-auto.sql
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_att_id_f_ahq60 foreign key (attachment_id)
+ references acs_objects(object_id);
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_ima_id_f_kz3mi foreign key (image_id)
+ references cms_images(image_id);
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_ite_id_f_wg1gi foreign key (item_id)
+ references cms_items(item_id);
+
+insert into cms_item_image_attachment
+(use_context, caption, image_id, item_id, attachment_id)
+select '', substr(map.caption, 0, 100), map.image_id, map.article_id, map.map_id
+from cms_article_image_map map;
+
+delete from cms_article_image_map;
+
+delete from cms_items
+where item_id in (
+ select object_id from acs_objects
+ where object_type = 'com.arsdigita.cms.ArticleImageAssociation' );
+
+delete from cms_published_links
+where pending_source in (
+ select object_id from acs_objects
+ where object_type = 'com.arsdigita.cms.ArticleImageAssociation' );
+
+update inits
+set class_name = 'com.arsdigita.cms.ItemImageAttachmentInitializer'
+where class_name = 'com.arsdigita.cms.AttachableImageInitializer';
+
+update acs_objects set
+object_type = 'com.arsdigita.cms.contenttypes.ItemImageAttachment',
+default_domain_class = 'com.arsdigita.cms.contenttypes.ItemImageAttachment'
+where object_type = 'com.arsdigita.cms.ArticleImageAssociation';
+
+update authoring_steps
+set label_key = 'com.arsdigita.cms.image_step_label', label_bundle = 'com.arsdigita.cms.ImageStepResources', description_key = 'com.arsdigita.cms.image_step_description', description_bundle = 'com.arsdigita.cms.ImageStepResources', component = 'com.arsdigita.cms.contenttypes.ui.ImageStep'
+where component = 'com.arsdigita.cms.ui.authoring.ArticleImage';
+
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.2.0-6.2.1.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.2.0-6.2.1.sql
new file mode 100755
index 000000000..868061fe7
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.2.0-6.2.1.sql
@@ -0,0 +1,23 @@
+--
+-- Copyright (C) 2005 Runtime Collective Ltd. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+-- $Id: alter-table-authoring_steps.sql 285 2005-02-22 00:29:02Z sskracic $
+-- $DateTime: 2004/08/17 23:15:09 $
+
+PROMPT ImageStep 6.2.0 -> 6.2.1 Upgrade Script (Oracle)
+
+@@ ../oracle-se/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.5.0-6.5.1.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.5.0-6.5.1.sql
new file mode 100644
index 000000000..a8e45dfa5
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/oracle-se-6.5.0-6.5.1.sql
@@ -0,0 +1,4 @@
+
+PROMPT ImageStep 6.5.0 -> 6.5.1 Upgrade Script (Oracle)
+
+@@ ../oracle-se/upgrade/6.5.0-6.5.1/add_link_column.sql
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-1.0.0-2.0.0.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-1.0.0-2.0.0.sql
new file mode 100755
index 000000000..c34ee8ac4
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-1.0.0-2.0.0.sql
@@ -0,0 +1,53 @@
+
+update acs_objects set
+object_type = 'com.arsdigita.cms.ReusableImageAsset',
+default_domain_class = 'com.arsdigita.cms.ReusableImageAsset'
+where object_type = 'com.arsdigita.cms.contenttypes.AttachableImage';
+
+drop table cms_attachable_images;
+
+
+
+
+@@ ../ddl/postgres/table-cms_item_image_attachment-auto.sql
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_att_id_f_ahq60 foreign key (attachment_id)
+ references acs_objects(object_id);
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_ima_id_f_kz3mi foreign key (image_id)
+ references cms_images(image_id);
+alter table cms_item_image_attachment add
+ constraint cms_ite_ima_att_ite_id_f_wg1gi foreign key (item_id)
+ references cms_items(item_id);
+
+
+insert into cms_item_image_attachment
+(use_context, caption, image_id, item_id, attachment_id)
+select '', map.caption, map.image_id, map.article_id, map.map_id
+from cms_article_image_map map;
+
+delete from cms_article_image_map;
+
+
+delete from cms_items
+where item_id in (
+ select object_id from acs_objects
+ where object_type = 'com.arsdigita.cms.ArticleImageAssociation' );
+
+delete from cms_published_links
+where pending_source in (
+ select object_id from acs_objects
+ where object_type = 'com.arsdigita.cms.ArticleImageAssociation' );
+
+update inits
+set class_name = 'com.arsdigita.cms.ItemImageAttachmentInitializer'
+where class_name = 'com.arsdigita.cms.AttachableImageInitializer';
+
+update acs_objects set
+object_type = 'com.arsdigita.cms.contenttypes.ItemImageAttachment',
+default_domain_class = 'com.arsdigita.cms.contenttypes.ItemImageAttachment'
+where object_type = 'com.arsdigita.cms.ArticleImageAssociation';
+
+update authoring_steps
+set label_key = 'com.arsdigita.cms.image_step_label', label_bundle = 'com.arsdigita.cms.ImageStepResources', description_key = 'com.arsdigita.cms.image_step_description', description_bundle = 'com.arsdigita.cms.ImageStepResources', component = 'com.arsdigita.cms.contenttypes.ui.ImageStep'
+where component = 'com.arsdigita.cms.ui.authoring.ArticleImage';
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.2.0-6.2.1.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.2.0-6.2.1.sql
new file mode 100755
index 000000000..6c09d39e5
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.2.0-6.2.1.sql
@@ -0,0 +1,27 @@
+--
+-- Copyright (C) 2005 Runtime Collective Ltd. All Rights Reserved.
+--
+-- This library is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser General Public License
+-- as published by the Free Software Foundation; either version 2.1 of
+-- the License, or (at your option) any later version.
+--
+-- This library is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-- Lesser General Public License for more details.
+--
+-- You should have received a copy of the GNU Lesser General Public
+-- License along with this library; if not, write to the Free Software
+-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+--
+-- $Id: alter-table-authoring_steps.sql 285 2005-02-22 00:29:02Z sskracic $
+-- $DateTime: 2004/08/17 23:15:09 $
+
+\echo ImageStep 6.2.0 -> 6.2.1 Upgrade Script (PostgreSQL)
+
+begin;
+
+\i ../postgres/upgrade/6.2.0-6.2.1/alter-table-cms_item_image_attachment.sql
+
+commit;
diff --git a/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.5.0-6.5.1.sql b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.5.0-6.5.1.sql
new file mode 100644
index 000000000..bff18b237
--- /dev/null
+++ b/ccm-cms-assets-imagestep/sql/ccm-cms-assets-imagestep/upgrade/postgres-6.5.0-6.5.1.sql
@@ -0,0 +1,7 @@
+\echo ImageStep 6.5.0 -> 6.5.1 Upgrade Script (PostgreSQL)
+
+begin;
+
+\i ../postgres/upgrade/6.5.0-6.5.1/add_link_column.sql
+
+commit;
diff --git a/ccm-cms-assets-imagestep/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contentassets/ItemImageAttachment.xml b/ccm-cms-assets-imagestep/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contentassets/ItemImageAttachment.xml
new file mode 100755
index 000000000..1f7ec32eb
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/WEB-INF/traversal-adapters/com/arsdigita/cms/contentassets/ItemImageAttachment.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.config b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.config
new file mode 100755
index 000000000..2b8f1bc8f
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.load b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.load
new file mode 100755
index 000000000..5a50c0fb6
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.load
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.upgrade b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.upgrade
new file mode 100755
index 000000000..c2272b611
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/ccm-cms-assets-imagestep.upgrade
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
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
new file mode 100755
index 000000000..aa3cf0ed3
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ImageStepResources.properties
@@ -0,0 +1,2 @@
+com.arsdigita.cms.contentassets.image_step_label=Add Images
+com.arsdigita.cms.contentassets.image_step_description=Add Images
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
new file mode 100755
index 000000000..c28d574f3
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachment.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.CustomCopy;
+import com.arsdigita.cms.ItemCopier;
+import com.arsdigita.cms.ReusableImageAsset;
+import com.arsdigita.cms.contenttypes.Link;
+import com.arsdigita.domain.DomainObject;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.kernel.ACSObject;
+// import com.arsdigita.persistence.DataAssociation;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.persistence.SessionManager;
+import com.arsdigita.persistence.metadata.Property;
+import com.arsdigita.util.Assert;
+import org.apache.log4j.Logger;
+
+/**
+ * @version $Revision: #3 $ $Date: 2004/04/08 $
+ * @version $Id: $
+ **/
+public class ItemImageAttachment extends ACSObject implements CustomCopy {
+
+ /** 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 IMAGE_ATTACHMENTS = "imageAttachments";
+ public static final String ITEM_ATTACHMENTS = "itemAttachments";
+ public static final String IMAGE_LINK = "imageLink";
+
+ /** 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 = new ItemImageAttachmentConfig();
+
+ static {
+ s_config.load();
+ }
+
+ private ItemImageAttachment() {
+ this(BASE_DATA_OBJECT_TYPE);
+ }
+
+ public ItemImageAttachment(DataObject obj) {
+ super(obj);
+ }
+
+ public ItemImageAttachment(String type) {
+ super(type);
+ }
+
+ public String getBaseDataObjectType() {
+ return BASE_DATA_OBJECT_TYPE;
+ }
+
+ public ItemImageAttachment( ContentItem item, ReusableImageAsset image ) {
+ this();
+
+ set( ITEM, item );
+ set( IMAGE, image );
+ }
+
+ public static ItemImageAttachment retrieve( OID oid ) {
+ return (ItemImageAttachment) DomainObjectFactory.newInstance( oid );
+ }
+
+ public static ItemImageAttachmentConfig getConfig() {
+ return s_config;
+ }
+ public ReusableImageAsset getImage() {
+ if( s_log.isDebugEnabled() )
+ s_log.debug( "Getting image for " + getOID() );
+
+ DataObject dobj = (DataObject) get( IMAGE );
+ Assert.exists( dobj );
+
+ return (ReusableImageAsset) DomainObjectFactory.newInstance( dobj );
+ }
+
+ public void setImage( ReusableImageAsset image ) {
+ Assert.exists( image, ReusableImageAsset.class );
+ set( IMAGE, image );
+ }
+
+ public ContentItem getItem() {
+ DataObject dobj = (DataObject) get( ITEM );
+ Assert.exists( dobj );
+
+ return (ContentItem) DomainObjectFactory.newInstance( dobj );
+ }
+
+ public void setItem( ContentItem item ) {
+ Assert.exists( item, ContentItem.class );
+ set( ITEM, item );
+ }
+
+ /** Retrieves links for a content item */
+ public static DataCollection getImageAttachments( ContentItem item ) {
+ Assert.exists( item, ContentItem.class );
+
+ if( s_log.isDebugEnabled() )
+ s_log.debug("Getting attachments for " + item.getOID() );
+
+ DataCollection attachments = SessionManager.getSession().retrieve
+ ( BASE_DATA_OBJECT_TYPE );
+ attachments.addEqualsFilter( ITEM + ".id", item.getID() );
+
+ return attachments;
+ }
+
+ public void setUseContext(String useContext) {
+ set(USE_CONTEXT, useContext);
+ }
+
+ public String getUseContext() {
+ return (String) get(USE_CONTEXT);
+ }
+
+ public void setCaption( String caption ) {
+ set( CAPTION, caption );
+ }
+
+ public String getCaption() {
+ return (String) get( CAPTION );
+ }
+
+ public void setTitle( String title ) {
+ set( TITLE, title );
+ }
+
+ public String getTitle() {
+ return (String) get( TITLE );
+ }
+
+ public void setDescription( String description) {
+ set( DESCRIPTION, description );
+ }
+
+ public String getDescription() {
+ return (String) get( DESCRIPTION );
+ }
+
+
+ /**
+ * Automatically publish an unpublished image
+ */
+ public boolean copyProperty( final CustomCopy source,
+ final Property property,
+ final ItemCopier copier ) {
+ String attribute = property.getName();
+ if( ItemCopier.VERSION_COPY == copier.getCopyType() &&
+ IMAGE.equals( attribute ) )
+ {
+ ItemImageAttachment attachment = (ItemImageAttachment) source;
+ ReusableImageAsset image = attachment.getImage();
+
+ ReusableImageAsset liveImage =
+ (ReusableImageAsset) image.getLiveVersion();
+
+ if( null == liveImage ) {
+ liveImage = (ReusableImageAsset) image.createLiveVersion();
+ }
+
+ setImage( liveImage );
+ return true;
+ }
+
+ return false;
+ }
+
+ // chris gilbert - optional link
+
+ public Link getLink() {
+ Link link = null;
+ DataObject dobj = (DataObject) get( IMAGE_LINK );
+ if (dobj != null) {
+
+ link = (Link) DomainObjectFactory.newInstance( dobj );
+ }
+ return link;
+ }
+
+ public void setLink( Link link ) {
+ Assert.exists( link, Link.class );
+ set( IMAGE_LINK, link );
+ }
+
+ public void removeLink() {
+ // 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));
+ set (IMAGE_LINK, null);
+ save();
+ link.delete();
+
+ }
+
+}
diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig.java
new file mode 100755
index 000000000..c6d23b6ba
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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;
+
+import com.arsdigita.runtime.AbstractConfig;
+import com.arsdigita.util.parameter.BooleanParameter;
+import com.arsdigita.util.parameter.Parameter;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * A record containing server-session scoped configuration properties.
+ *
+ * Accessors of this class may return null. Developers should take
+ * care to trap null return values in their code.
+ *
+ * @see ContentSection#getConfig()
+ *
+ * @author Justin Ross <jross@redhat.com>
+ * @version $Id: $
+ */
+public final class ItemImageAttachmentConfig extends AbstractConfig {
+
+ private static final Logger s_log = Logger.getLogger(ItemImageAttachmentConfig.class);
+
+ // Are the description and title properties available for
+ // display/editing. These properties are used by the
+ // ImageGallery content type.
+ private final Parameter m_isImageStepDescriptionAndTitleShown;
+
+ /**
+ * Do not instantiate this class directly.
+ *
+ * @see ContentSection#getConfig()
+ **/
+ public ItemImageAttachmentConfig() {
+
+ m_isImageStepDescriptionAndTitleShown = new BooleanParameter
+ ("com.arsdigita.cms.m_is_image_step_description_and_title_shown",
+ Parameter.REQUIRED, new Boolean(false));
+
+
+ register(m_isImageStepDescriptionAndTitleShown);
+
+ loadInfo();
+ }
+
+ public final boolean getIsImageStepDescriptionAndTitleShown() {
+ return ((Boolean) get(m_isImageStepDescriptionAndTitleShown)).booleanValue();
+ }
+}
diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig_parameter.properties b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig_parameter.properties
new file mode 100755
index 000000000..3c7584cc3
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentConfig_parameter.properties
@@ -0,0 +1,4 @@
+com.arsdigita.cms.m_is_image_step_description_and_title_shown.title=Are attached image titles and descriptions available
+com.arsdigita.cms.m_is_image_step_description_and_title_shown.purpose=Should the description and title properties be available for attached images
+com.arsdigita.cms.m_is_image_step_description_and_title_shown.example=false
+com.arsdigita.cms.m_is_image_step_description_and_title_shown.format=[boolean]
\ No newline at end of file
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
new file mode 100755
index 000000000..bdaf83b35
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ItemImageAttachmentInitializer.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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;
+
+import com.arsdigita.cms.AuthoringKit;
+import com.arsdigita.cms.AuthoringKitStepAssociation;
+import com.arsdigita.cms.AuthoringStep;
+import com.arsdigita.cms.ContentPage;
+import com.arsdigita.cms.basetypes.Article;
+import com.arsdigita.cms.contenttypes.ContentAssetInitializer;
+// import com.arsdigita.cms.contentassets.ItemImageAttachment;
+import com.arsdigita.cms.contentassets.ui.ImageStep;
+import com.arsdigita.domain.DomainObject;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.domain.DomainObjectInstantiator;
+import com.arsdigita.globalization.GlobalizedMessage;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.persistence.PersistenceException;
+import com.arsdigita.persistence.SessionManager;
+import com.arsdigita.persistence.metadata.ObjectType;
+import com.arsdigita.runtime.DomainInitEvent;
+
+/**
+ * @version $Id: ItemImageAttachmentInitializer.java 287 2005-02-22 00:29:02Z sskracic $
+ */
+public class ItemImageAttachmentInitializer extends ContentAssetInitializer {
+
+ public ItemImageAttachmentInitializer() {
+ super("ccm-cms-assets-imagestep.pdl.mf");
+ }
+
+ @Override
+ public void init( DomainInitEvent ev ) {
+
+ super.init(ev);
+
+ DomainObjectFactory.registerInstantiator(
+ ItemImageAttachment.BASE_DATA_OBJECT_TYPE,
+ new DomainObjectInstantiator() {
+ protected DomainObject doNewInstance( DataObject obj ) {
+ return new ItemImageAttachment( obj );
+ }
+
+ @Override
+ public DomainObjectInstantiator resolveInstantiator( DataObject obj ) {
+ return this;
+ }
+ }
+ );
+
+ removeDeprecatedImageSteps();
+ }
+
+ /**
+ *
+ */
+ private void removeDeprecatedImageSteps() {
+ DataCollection steps = SessionManager.getSession().retrieve
+ ( AuthoringStep.BASE_DATA_OBJECT_TYPE );
+
+ // Don't use defined constant to reduce dependency on Article
+ steps.addEqualsFilter( "component",
+ "com.arsdigita.cms.ui.authoring.ArticleImage" );
+
+ while( steps.next() ) {
+ DataObject step = steps.getDataObject();
+
+ DataCollection kits = SessionManager.getSession().retrieve
+ ( AuthoringKitStepAssociation.BASE_DATA_OBJECT_TYPE );
+ kits.addEqualsFilter( "stepId", step.get( "id" ) );
+
+ while( kits.next() ) {
+ DataObject kitStep = kits.getDataObject();
+ AuthoringKitStepAssociation kitStepAsso = new AuthoringKitStepAssociation(kitStep);
+ // Check whether the content type is (persistence-wise) subtype
+ // of com.ad.cms.Article. This is lame, but I couldn't find a better API to do this:
+ AuthoringKit kit = new AuthoringKit (kitStepAsso.getKitID());
+ try {
+ ObjectType.verifySubtype(Article.BASE_DATA_OBJECT_TYPE,
+ kit.getContentType().getAssociatedObjectType());
+ kitStepAsso.delete();
+ } catch (PersistenceException pe) {
+ // Do nothing, the content type is not subtyping com.arsdigita.cms.Article
+ }
+ }
+
+ // DomainObjectFactory.newInstance( step ).delete();
+ }
+ }
+
+
+ public String getTraversalXML() {
+ return "/WEB-INF/traversal-adapters/com/arsdigita/" +
+ "cms/contentassets/ItemImageAttachment.xml";
+ }
+
+ public String getProperty() {
+ return "imageAttachments";
+ }
+
+ public String getBaseType() {
+ return ContentPage.BASE_DATA_OBJECT_TYPE;
+ }
+
+ public Class getAuthoringStep() {
+ return ImageStep.class;
+ }
+
+ public GlobalizedMessage getAuthoringStepLabel() {
+ return new GlobalizedMessage("com.arsdigita.cms.contentassets.image_step_label",
+ "com.arsdigita.cms.contentassets.ImageStepResources");
+ }
+
+ public GlobalizedMessage getAuthoringStepDescription() {
+ return new GlobalizedMessage("com.arsdigita.cms.contentassets.image_step_description",
+ "com.arsdigita.cms.contentassets.ImageStepResources");
+ }
+
+ public int getAuthoringStepSortKey() {
+ return 1; // XXX config param please
+ }
+}
diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/ImagePropertyRenderer.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/ImagePropertyRenderer.java
new file mode 100755
index 000000000..fbeadb3cc
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/ImagePropertyRenderer.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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.imagestep;
+
+import com.arsdigita.london.navigation.DataCollectionPropertyRenderer;
+
+import com.arsdigita.cms.ReusableImageAsset;
+import com.arsdigita.cms.contentassets.ItemImageAttachment;
+
+import com.arsdigita.persistence.DataAssociation;
+import com.arsdigita.persistence.DataAssociationCursor;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.DataObject;
+import com.arsdigita.util.UncheckedWrapperException;
+import com.arsdigita.xml.Element;
+
+/**
+ * Classes implementing this interface will render in XML a property which
+ * will normally have been previously added to a
+ * DataCollectionDefinition.
+ */
+public class ImagePropertyRenderer implements DataCollectionPropertyRenderer {
+ public static final String XML_NS =
+ "http://ccm.redhat.com/london/image_attachments";
+
+ /**
+ * Called from DataCollectionRenderer for every returned item. This method
+ * will add XML for the property to the renderer's output.
+ */
+ public void render( DataCollection dc, Element parent ) {
+
+ Object images = dc.get( ItemImageAttachment.IMAGE_ATTACHMENTS );
+ if( null == images ) return;
+
+ if( images instanceof DataObject ) {
+ Element root = rootElement( parent );
+ render( (DataObject) images, root );
+ }
+
+ else if( images instanceof DataAssociation ) {
+ // XXX: Unused, untested code path
+ DataAssociationCursor cursor = ((DataAssociation) images).cursor();
+
+ Element root = null;
+ while( cursor.next() ) {
+ if( null == root ) root = rootElement( parent );
+ render( cursor.getDataObject(), root );
+ }
+ }
+
+ else {
+ throw new UncheckedWrapperException(
+ "While trying to render image property, " +
+ ItemImageAttachment.IMAGE_ATTACHMENTS +
+ " association returned a " + images.getClass().getName() +
+ " (" + images.toString() +
+ "). Expected either a DataObject or a DataAssociation."
+ );
+ }
+ }
+
+ private void render( DataObject obj, Element root ) {
+ Element ia = root.newChildElement( "ia:imageAttachment", XML_NS );
+
+ DataObject image = (DataObject) obj.get( ItemImageAttachment.IMAGE );
+
+ Object context = obj.get( ItemImageAttachment.USE_CONTEXT );
+ Object description = obj.get( ItemImageAttachment.DESCRIPTION );
+ Object title = obj.get( ItemImageAttachment.TITLE );
+ Object caption = obj.get( ItemImageAttachment.CAPTION );
+ Object imageID = image.get( ReusableImageAsset.ID );
+ Object width = image.get( ReusableImageAsset.WIDTH );
+ Object height = image.get( ReusableImageAsset.HEIGHT );
+
+ Element imageIDE = ia.newChildElement( "ia:imageID", XML_NS );
+ imageIDE.setText( imageID.toString() );
+
+ if( null != context ) {
+ Element contextE = ia.newChildElement( "ia:context", XML_NS );
+ contextE.setText( context.toString() );
+ }
+
+ if( null != caption ) {
+ Element captionE = ia.newChildElement( "ia:caption", XML_NS );
+ captionE.setText( caption.toString() );
+ }
+
+ if( null != title) {
+ Element titleE = ia.newChildElement( "ia:title", XML_NS );
+ titleE.setText( title.toString() );
+ }
+
+ if( null != description) {
+ Element descriptionE = ia.newChildElement( "ia:description", XML_NS );
+ descriptionE.setText( title.toString() );
+ }
+
+ if( null != width ) {
+ Element widthE = ia.newChildElement( "ia:width", XML_NS );
+ widthE.setText( width.toString() );
+ }
+
+ if( null != height ) {
+ Element heightE = ia.newChildElement( "ia:height", XML_NS );
+ heightE.setText( height.toString() );
+ }
+ }
+
+ private Element rootElement( Element parent ) {
+ return parent.newChildElement( "ia:imageAttachments", XML_NS );
+ }
+}
diff --git a/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/SingleImageProperty.java b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/SingleImageProperty.java
new file mode 100755
index 000000000..9c9ccc604
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/imagestep/SingleImageProperty.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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.imagestep;
+
+import com.arsdigita.london.navigation.DataCollectionProperty;
+
+import com.arsdigita.persistence.CompoundFilter;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.FilterFactory;
+
+import com.arsdigita.cms.ReusableImageAsset;
+import com.arsdigita.cms.contentassets.ItemImageAttachment;
+
+/**
+ * Add a single image with a specific context.
+ */
+public class SingleImageProperty implements DataCollectionProperty {
+ private String m_context;
+
+ private static final String IMAGE_ID =
+ ItemImageAttachment.IMAGE_ATTACHMENTS + "." +
+ ItemImageAttachment.IMAGE + "." +
+ ReusableImageAsset.ID;
+
+ private static final String WIDTH =
+ ItemImageAttachment.IMAGE_ATTACHMENTS + "." +
+ ItemImageAttachment.IMAGE + "." +
+ ReusableImageAsset.WIDTH;
+
+ private static final String HEIGHT =
+ ItemImageAttachment.IMAGE_ATTACHMENTS + "." +
+ ItemImageAttachment.IMAGE + "." +
+ ReusableImageAsset.HEIGHT;
+
+ private static final String CAPTION =
+ ItemImageAttachment.IMAGE_ATTACHMENTS + "." +
+ ItemImageAttachment.CAPTION;
+
+ private static final String CONTEXT =
+ ItemImageAttachment.IMAGE_ATTACHMENTS + "." +
+ ItemImageAttachment.USE_CONTEXT;
+
+ /**
+ * Create a SingleImageProperty which will pull out a single
+ * ItemImageAttachment with the given use context.
+ */
+ public SingleImageProperty( String context ) {
+ m_context = context;
+ }
+
+ public void addProperty( DataCollection dc ) {
+ dc.addPath( IMAGE_ID );
+ dc.addPath( WIDTH );
+ dc.addPath( HEIGHT );
+ dc.addPath( CAPTION );
+ dc.addPath( CONTEXT );
+
+ FilterFactory ff = dc.getFilterFactory();
+ CompoundFilter or = ff.or();
+
+ or.addFilter( ff.equals( CONTEXT, m_context ) );
+ or.addFilter( ff.equals( IMAGE_ID, null ) );
+
+ dc.addFilter( or );
+ }
+}
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
new file mode 100755
index 000000000..cb3680801
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStep.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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.cms.contentassets.ItemImageAttachment;
+
+import com.arsdigita.bebop.AbstractSingleSelectionModel;
+import com.arsdigita.bebop.Page;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.RequestLocal;
+import com.arsdigita.bebop.event.ActionEvent;
+import com.arsdigita.bebop.event.ActionListener;
+import com.arsdigita.bebop.parameters.ParameterModel;
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ui.SecurityPropertyEditor;
+import com.arsdigita.cms.ui.authoring.AuthoringKitWizard;
+import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.toolbox.ui.OIDParameter;
+
+import java.util.Iterator;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Pluggable authoring step to add an ImageAsset to a content item
+ * Currently only supports adding one image though the PDL has
+ * association for multiple.
+ */
+
+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;
+
+ public ImageStep( ItemSelectionModel itemModel,
+ AuthoringKitWizard parent ) {
+ super();
+
+ m_itemSelection = itemModel;
+ m_parent = parent;
+
+ m_attachmentOID = new OIDParameter( "attachmentID" );
+ m_attachmentSelection = new AttachmentSelectionModel();
+
+ m_add = new ImageStepEdit( this );
+ WorkflowLockedComponentAccess addCA =
+ new WorkflowLockedComponentAccess( m_add, m_itemSelection );
+ addComponent( "add", "Add Image", addCA );
+
+ m_display = new ImageStepDisplay( this );
+ setDisplayComponent(m_display);
+
+ Iterator imageComponents = m_add.getImageComponents();
+ while( imageComponents.hasNext() ) {
+ ImageStepEdit.ImageComponent component =
+ (ImageStepEdit.ImageComponent) imageComponents.next();
+
+ addListeners( component.getForm(),
+ component.getSaveCancelSection().getCancelButton() );
+ }
+
+ m_parent.getList().addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent event) {
+ PageState state = event.getPageState();
+ showDisplayPane(state);
+ }
+ });
+ }
+
+ public void register( Page p ) {
+ super.register( p );
+
+ p.addComponentStateParam( this, m_attachmentOID );
+ }
+
+ /**
+ * @return the parent wizard
+ */
+ public AuthoringKitWizard getParentWizard() {
+ return m_parent;
+ }
+
+ /**
+ * @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 ItemImageAttachment getAttachment( PageState ps ) {
+ return (ItemImageAttachment)
+ m_attachmentSelection.getSelectedAttachment( ps );
+ }
+
+ private class AttachmentSelectionModel
+ extends AbstractSingleSelectionModel
+ {
+ private final RequestLocal m_attachment = new RequestLocal() {
+ protected Object initialValue( PageState ps ) {
+ OID oid = (OID) getSelectedKey( ps );
+ if( null == oid ) return null;
+
+ return DomainObjectFactory.newInstance( oid );
+ }
+ };
+
+ public Object getSelectedKey( PageState ps ) {
+ OID oid = (OID) ps.getValue( m_attachmentOID );
+ if( null == oid ) return null;
+
+ return oid;
+ }
+
+ public void setSelectedKey( PageState ps, Object oid ) {
+ m_attachment.set( ps, null );
+ ps.setValue( m_attachmentOID, oid );
+ }
+
+ 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;
+ }
+ }
+}
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
new file mode 100755
index 000000000..96c49ceb1
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepDisplay.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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.cms.contentassets.ItemImageAttachment;
+
+import com.arsdigita.bebop.BoxPanel;
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.ControlLink;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.List;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.SimpleContainer;
+import com.arsdigita.bebop.event.PrintEvent;
+import com.arsdigita.bebop.event.PrintListener;
+import com.arsdigita.bebop.list.ListCellRenderer;
+import com.arsdigita.bebop.list.ListModel;
+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.ui.ImageDisplay;
+import com.arsdigita.domain.DomainObjectFactory;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.persistence.OID;
+import com.arsdigita.util.LockableImpl;
+import com.arsdigita.xml.Element;
+
+import javax.servlet.ServletException;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Pluggable authoring step to add an ImageAsset to a content item
+ * Currently only supports adding one image though the PDL has
+ * association for multiple.
+ */
+
+public class ImageStepDisplay extends SimpleContainer {
+ private static final Logger s_log = Logger.getLogger(ImageStepDisplay.class);
+
+ private final ImageStep m_imageStep;
+
+ private final static String DELETE = "deleteAttachment";
+
+ public ImageStepDisplay( ImageStep step ) {
+ super();
+
+ m_imageStep = step;
+
+ Label mainLabel = new Label
+ ("This item does not have any associated images.");
+ mainLabel.setFontWeight(Label.ITALIC);
+
+ List imageList = new List( new ImageListModelBuilder() ) {
+ public void respond( PageState ps ) throws ServletException {
+ if( DELETE.equals( ps.getControlEventName() ) ) {
+ String attachment = ps.getControlEventValue();
+
+ OID oid = OID.valueOf( attachment );
+ DomainObjectFactory.newInstance( oid ).delete();
+ }
+
+ else {
+ super.respond( ps );
+ }
+ }
+ };
+ imageList.setCellRenderer( new ImageListCellRenderer() );
+ imageList.setEmptyView( mainLabel );
+
+ add( imageList );
+ }
+
+ private class ImageListModelBuilder extends LockableImpl
+ implements ListModelBuilder {
+ 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 );
+
+
+ return new ImageListModel( attachments );
+ }
+ }
+
+ private class ImageListModel implements ListModel {
+ private final DataCollection m_attachments;
+
+ ImageListModel( DataCollection attachments ) {
+ m_attachments = attachments;
+ }
+
+ public Object getElement() {
+ return DomainObjectFactory.newInstance
+ ( m_attachments.getDataObject() );
+ }
+
+ public String getKey() {
+ return m_attachments.getDataObject().getOID().toString();
+ }
+
+ public boolean next() {
+ return m_attachments.next();
+ }
+ }
+
+ private class ImageListCellRenderer implements ListCellRenderer {
+ 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 );
+
+ container.add( new ImageDisplay(null) {
+ protected void generateImagePropertiesXML( ImageAsset image,
+ PageState state,
+ Element element ) {
+ super.generateImagePropertiesXML(image, state, element);
+
+ String caption = attachment.getCaption();
+ if (caption != null) {
+ element.addAttribute("caption", caption);
+ }
+
+ // We check here to see whether IsImageStepDescriptionAndTitleShown
+ // is set to true. If it is, we display the description and title options
+ if(ItemImageAttachment.getConfig().getIsImageStepDescriptionAndTitleShown()) {
+ String description = attachment.getDescription();
+ if (description != null) {
+ element.addAttribute("description", description);
+ }
+
+ String title = attachment.getTitle();
+ if (title!= null) {
+ element.addAttribute("title", title);
+ }
+ }
+
+
+ }
+
+ protected ImageAsset getImageAsset( PageState ps ) {
+ return attachment.getImage();
+ }
+ } );
+
+ BoxPanel useContextPanel = new BoxPanel( BoxPanel.HORIZONTAL );
+ useContextPanel.add( new Label( "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( "Unknown" );
+ } else {
+ l.setLabel( useContext );
+ }
+ }
+ } );
+ useContextLabel.setOutputEscaping( false );
+ useContextPanel.add( useContextLabel );
+ container.add( useContextPanel );
+
+ ControlLink delete = new ControlLink( "Delete" ) {
+ public void setControlEvent( PageState ps ) {
+ String oid = ps.getControlEventValue();
+ ps.setControlEvent( list, DELETE, oid );
+ }
+ };
+ container.add( delete );
+
+ 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
new file mode 100755
index 000000000..75b8332e5
--- /dev/null
+++ b/ccm-cms-assets-imagestep/src/com/arsdigita/cms/contentassets/ui/ImageStepEdit.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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.cms.contentassets.ItemImageAttachment;
+
+import com.arsdigita.bebop.ActionLink;
+import com.arsdigita.bebop.ColumnPanel;
+import com.arsdigita.bebop.Component;
+import com.arsdigita.bebop.Form;
+import com.arsdigita.bebop.FormProcessException;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.MapComponentSelectionModel;
+import com.arsdigita.bebop.Page;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.ParameterSingleSelectionModel;
+import com.arsdigita.bebop.SaveCancelSection;
+import com.arsdigita.bebop.SimpleContainer;
+import com.arsdigita.bebop.event.ActionEvent;
+import com.arsdigita.bebop.event.ActionListener;
+import com.arsdigita.bebop.event.FormInitListener;
+import com.arsdigita.bebop.event.FormProcessListener;
+import com.arsdigita.bebop.event.FormSectionEvent;
+import com.arsdigita.bebop.event.ParameterEvent;
+import com.arsdigita.bebop.event.ParameterListener;
+import com.arsdigita.bebop.form.TextField;
+import com.arsdigita.bebop.form.TextArea;
+import com.arsdigita.bebop.parameters.BigDecimalParameter;
+import com.arsdigita.bebop.parameters.NotNullValidationListener;
+import com.arsdigita.bebop.parameters.StringLengthValidationListener;
+import com.arsdigita.bebop.parameters.ParameterData;
+import com.arsdigita.bebop.parameters.StringParameter;
+import com.arsdigita.domain.DataObjectNotFoundException;
+import com.arsdigita.persistence.DataCollection;
+import com.arsdigita.util.Assert;
+import com.arsdigita.util.StringUtils;
+
+import com.arsdigita.cms.ContentItem;
+import com.arsdigita.cms.ImageAsset;
+import com.arsdigita.cms.ItemSelectionModel;
+import com.arsdigita.cms.ReusableImageAsset;
+import com.arsdigita.cms.ui.FileUploadSection;
+import com.arsdigita.cms.ui.ImageBrowser;
+import com.arsdigita.cms.ui.ImageChooser;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+public class ImageStepEdit extends SimpleContainer
+ implements FormProcessListener, FormInitListener {
+
+ private static final Logger s_log = Logger.getLogger(ImageStepEdit.class);
+
+ private final ImageStep m_imageStep;
+
+ private final StringParameter m_imageComponentKey;
+ private final MapComponentSelectionModel m_imageComponent;
+
+ private final String UPLOAD = "upload";
+ private final String LIBRARY = "library";
+
+ public ImageStepEdit( ImageStep step ) {
+ m_imageStep = step;
+
+ m_imageComponentKey = new StringParameter( "imageComponent" );
+
+ ParameterSingleSelectionModel componentModel =
+ new ParameterSingleSelectionModel( m_imageComponentKey );
+ m_imageComponent =
+ new MapComponentSelectionModel( componentModel, new HashMap() );
+
+ Map selectors = m_imageComponent.getComponentsMap();
+
+ ImageUploadComponent upload = new ImageUploadComponent();
+ upload.getForm().addInitListener(this);
+ upload.getForm().addProcessListener(this);
+ selectors.put( UPLOAD, upload );
+ add( upload );
+
+ ImageLibraryComponent library = new ImageLibraryComponent();
+ library.getForm().addInitListener(this);
+ library.getForm().addProcessListener(this);
+ selectors.put( LIBRARY, library );
+ add( library );
+ }
+
+ @Override
+ public void register( Page p ) {
+ super.register( p );
+
+ Map componentsMap = m_imageComponent.getComponentsMap();
+ Iterator i = componentsMap.keySet().iterator();
+ while( i.hasNext() ) {
+ Object key = i.next();
+ Component component = (Component) componentsMap.get( key );
+
+ p.setVisibleDefault( component, UPLOAD.equals( key ) );
+ }
+
+ p.addComponentStateParam( this, m_imageComponentKey );
+ }
+
+ Iterator getImageComponents() {
+ return m_imageComponent.getComponentsMap().values().iterator();
+ }
+
+ private 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, UPLOAD );
+ }
+
+ return (ImageComponent) m_imageComponent.getComponent( ps );
+
+ }
+
+ private void setImageComponent( PageState ps, final String activeKey ) {
+ m_imageComponent.setSelectedKey( ps, 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 );
+
+ boolean isVisible = activeKey.equals( key );
+
+ if( s_log.isDebugEnabled() ) {
+ s_log.debug( "Key: " + key + "; Visibility: " + isVisible );
+ }
+
+ ps.setVisible( component, isVisible );
+ }
+ }
+
+ public void init(FormSectionEvent event)
+ throws FormProcessException {
+ PageState ps = event.getPageState();
+
+ ItemImageAttachment attachment = m_imageStep.getAttachment( ps );
+ if( null == attachment ) return;
+
+ // XXX: Do something
+ }
+
+ public void process( FormSectionEvent event ) throws FormProcessException {
+ PageState ps = event.getPageState();
+ ImageComponent component = getImageComponent( ps );
+
+ if( !component.getSaveCancelSection().getSaveButton().isSelected( ps ) )
+ return;
+
+ ContentItem item = m_imageStep.getItem( ps );
+ if( null == item ) {
+ s_log.error( "No item selected in ImageStepEdit",
+ new RuntimeException() );
+ return;
+ }
+
+ ReusableImageAsset image = component.getImage( event );
+
+ ItemImageAttachment attachment = m_imageStep.getAttachment( ps );
+ if( null == attachment ) {
+ attachment = new ItemImageAttachment( item, image );
+ }
+ attachment.setCaption( component.getCaption( event ) );
+
+ // We only set the description and title based on the UI in
+ // the case where getIsImageStepDescriptionAndTitleShown is true.
+ // Otherwise, we leave this as the default value. This means
+ // existing values are not overwritten if the image is edited when
+ // isImageStepDescriptionAndTitleShown is false.
+ if(ItemImageAttachment.getConfig().getIsImageStepDescriptionAndTitleShown()) {
+ attachment.setDescription(component.getDescription( event ));
+ attachment.setTitle(component.getTitle( event ));
+ }
+ attachment.setUseContext( component.getUseContext( event ) );
+ }
+
+ interface ImageComponent {
+ ReusableImageAsset getImage( FormSectionEvent event )
+ throws FormProcessException;
+ String getCaption( FormSectionEvent event );
+ String getDescription( FormSectionEvent event );
+ String getTitle( FormSectionEvent event );
+ String getUseContext( FormSectionEvent event );
+ SaveCancelSection getSaveCancelSection();
+ Form getForm();
+ }
+
+ private 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;
+
+ public ImageUploadComponent() {
+ super("imageStepEditUpload", new ColumnPanel(2));
+
+ setEncType("multipart/form-data");
+
+ // Ignoring deprecated constructor.
+ m_imageFile = new FileUploadSection("Image Type",
+ "image", ImageAsset.MIME_JPEG);
+ m_imageFile.getFileUploadWidget()
+ .addValidationListener(new NotNullValidationListener());
+
+ add( m_imageFile, ColumnPanel.FULL_WIDTH );
+
+ add(new Label("Caption"));
+ m_caption = new TextField("caption");
+ m_caption.addValidationListener(new NotNullValidationListener());
+ m_caption.addValidationListener(new StringLengthValidationListener(40));
+ m_caption.setSize(40);
+ add(m_caption);
+
+ m_title = new TextField("title");
+ m_description = new TextArea("description");
+
+ // We only show the title and description fields in the case where
+ // getIsImageStepDescriptionAndTitleShown is false.
+ if (ItemImageAttachment.getConfig().getIsImageStepDescriptionAndTitleShown()) {
+ add(new Label("Title"));
+ m_title.addValidationListener(new NotNullValidationListener());
+ m_title.setSize(40);
+ m_title.addValidationListener(new StringLengthValidationListener(40));
+ add(m_title);
+
+ add(new Label("Description"));
+ m_description.addValidationListener(new NotNullValidationListener());
+ m_description.addValidationListener(new StringLengthValidationListener(600));
+ m_description.setCols(30);
+ m_description.setRows(5);
+ add(m_description);
+
+ }
+
+ add(new Label("Use Context"));
+ m_useContext = new TextField("useContext");
+ m_useContext.setSize(40);
+ m_useContext.addValidationListener( new UniqueUseContextListener() );
+ add(m_useContext);
+
+ m_saveCancel = new SaveCancelSection();
+ add(m_saveCancel);
+
+ 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;
+ }
+
+ 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 ) {
+ 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 );
+ }
+
+ 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 );
+ }
+
+ public String getUseContext( FormSectionEvent event ) {
+ PageState ps = event.getPageState();
+ return (String) m_useContext.getValue( ps );
+ }
+
+ public Form getForm() {
+ return this;
+ }
+ }
+
+ private class ImageLibraryComponent extends SimpleContainer
+ implements ImageComponent {
+ private final ImageChooser m_chooser;
+ private final ItemSelectionModel m_imageModel;
+ private final BigDecimalParameter m_imageID;
+
+ private final Form m_form;
+ private final TextField m_caption;
+ private final TextField m_description;
+ private final TextField m_title;
+ private final TextField m_useContext;
+ private final SaveCancelSection m_saveCancel;
+
+ public ImageLibraryComponent() {
+ m_imageID = new BigDecimalParameter( "imageID" );
+ m_imageModel = new ItemSelectionModel( m_imageID );
+
+ m_chooser = new ImageChooser( ContentItem.DRAFT );
+ m_chooser.addImageActionListener( new ImageBrowser.LinkActionListener() {
+ public void deleteClicked( PageState ps, BigDecimal imageID ) {
+ s_log.debug( "Clicked delete" );
+
+ ReusableImageAsset image =
+ new ReusableImageAsset( imageID );
+ image.delete();
+ }
+
+ public void linkClicked( PageState ps, BigDecimal imageID ) {
+ s_log.debug( "Clicked select" );
+ try {
+ ReusableImageAsset image =
+ new ReusableImageAsset( imageID );
+
+ m_imageModel.setSelectedObject( ps, image );
+ } catch( DataObjectNotFoundException ex ) {
+ s_log.error( "Selected non-existant image: " + imageID, ex );
+ }
+ }
+ } );
+ // Don't display the delete links
+ /*
+ m_chooser.getImageBrowser().getColumn(5)
+ .setCellRenderer( new TableCellRenderer() {
+ public Component getComponent( Table table, PageState state,
+ Object value, boolean isSelected,
+ Object key, int row,
+ int column ) {
+ return new Label( " ", false );
+ }
+ } );
+ */
+ add( m_chooser );
+
+ m_form = new Form( "imageStepEditLibrary", new ColumnPanel( 2 ) );
+ add( m_form );
+
+ m_form.add(new Label("Caption"));
+ m_caption = new TextField("caption");
+ m_caption.addValidationListener(new NotNullValidationListener());
+ m_caption.setSize(40);
+ m_form.add(m_caption);
+
+ m_description = new TextField("description");
+ m_description.addValidationListener(new NotNullValidationListener());
+ m_description.setSize(40);
+
+ m_title = new TextField("title");
+ m_title.addValidationListener(new NotNullValidationListener());
+ m_title.setSize(40);
+
+ // Only show the title and description fields where these have
+ // been explicitly requested.
+ if (ItemImageAttachment.getConfig().getIsImageStepDescriptionAndTitleShown()) {
+ m_form.add(new Label("Description"));
+ m_form.add(m_description);
+ m_form.add(new Label("Title"));
+ m_form.add(m_title);
+ }
+
+
+ m_form.add(new Label("Use Context"));
+ m_useContext = new TextField("useContext");
+ m_useContext.setSize(40);
+ m_useContext.addValidationListener( new UniqueUseContextListener() );
+ m_form.add(m_useContext);
+
+ m_saveCancel = new SaveCancelSection();
+ m_form.add(m_saveCancel);
+
+ ActionLink upload = new ActionLink( "Upload a new image" );
+ upload.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent ev ) {
+ setImageComponent( ev.getPageState(), UPLOAD );
+ }
+ } );
+ add( upload, ColumnPanel.FULL_WIDTH );
+ }
+
+ public ReusableImageAsset getImage( FormSectionEvent event ) {
+ PageState ps = event.getPageState();
+
+ return (ReusableImageAsset) m_imageModel.getSelectedItem( ps );
+ }
+
+ @Override
+ public void register( Page p ) {
+ super.register( p );
+
+ p.addComponentStateParam( this, m_imageID );
+ }
+
+ 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 );
+ }
+
+ 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 m_form;
+ }
+
+ public SaveCancelSection getSaveCancelSection() {
+ return m_saveCancel;
+ }
+ }
+
+ private class UniqueUseContextListener implements ParameterListener {
+ public void validate( ParameterEvent ev )
+ throws FormProcessException
+ {
+ PageState ps = ev.getPageState();
+ ParameterData data = ev.getParameterData();
+
+ ContentItem item = m_imageStep.getItem( ps );
+ Assert.exists( item, ContentItem.class );
+
+ String value = data.getValue().toString();
+ value = StringUtils.trimleft( value );
+ if( StringUtils.emptyString( value ) ) {
+ value = null;
+ }
+ data.setValue( value );
+
+ DataCollection attachments =
+ ItemImageAttachment.getImageAttachments( item );
+ attachments
+ .addEqualsFilter(ItemImageAttachment.USE_CONTEXT, value );
+
+ try {
+ if( attachments.next() ) {
+ ItemImageAttachment attachment = m_imageStep.getAttachment( ps );
+ BigDecimal dupAttachmentID = (BigDecimal)
+ attachments.get( ItemImageAttachment.ID );
+
+ if( null == attachment ||
+ !attachment.getID().equals( dupAttachmentID ) )
+ {
+ data.addError( "There is already an image for this " +
+ "item with this context" );
+ }
+ }
+ } finally {
+ attachments.close();
+ }
+ }
+ }
+}