/* * 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.ui; import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.FormData; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.FormSection; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.FormSubmissionListener; import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.event.PrintListener; import com.arsdigita.bebop.form.Hidden; import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.util.BebopConstants; import com.arsdigita.cms.CMS; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentTypeLifecycleDefinition; import com.arsdigita.cms.Folder; import com.arsdigita.cms.ContentCenter; import com.arsdigita.cms.ContentCenterServlet; import com.arsdigita.cms.lifecycle.LifecycleDefinition; import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.web.ParameterMap; import com.arsdigita.web.URL; import com.arsdigita.workflow.simple.Workflow; import java.util.Date; import org.apache.log4j.Logger; /** * A class representing a content item search field in an HTML form. * * @author Scott Seago (sseago@redhat.com) * @version $Id: ItemSearchWidget.java 1166 2006-06-14 11:45:15Z fabrice $ */ public class ItemSearchWidget extends FormSection implements BebopConstants, FormSubmissionListener, FormInitListener { private static final Logger s_log = Logger.getLogger(ItemSearchWidget.class); //private Hidden m_selected; private TextField m_selected; private TextField m_item; private Hidden m_publish; private Submit m_search; private Submit m_clear; private Label m_jsLabel; private Label m_topHR; private Label m_bottomHR; private ContentType m_contentType; private ItemSearchSectionInline m_searchComponent; private String m_name; private String m_searchName; private String m_clearName; private Folder m_defaultCreationFolder; private String m_queryField; private ParameterModel m_model; private ParameterModel m_searchModel; private boolean disableCreatePane = false; private boolean editAfterCreate = true; private GlobalizedMessage searchLabelText = GlobalizationUtil.globalize( "cms.ui.item_search.search"); private GlobalizedMessage selectedLabelText = GlobalizationUtil.globalize( "cms.ui.item_search.selected"); public static final String BEBOP_ITEM_SEARCH = "bebop:itemSearch"; public static final String SEARCH = "search"; public static final boolean LIMIT_TO_CONTENT_SECTION = false; public static final String PUBLISH = "publish"; private class ItemFragment extends TextField { private ItemSearchWidget parent; public ItemFragment(ParameterModel parameter, ItemSearchWidget parent) { super(parameter); this.parent = parent; this.setReadOnly(); this.setSize(35); } } private class SearchFragment extends Submit { private ItemSearchWidget parent; public SearchFragment(String name, ItemSearchWidget parent) { super(name, GlobalizationUtil.globalize("cms.ui.search")); this.parent = parent; this.setAttribute("onClick", "return " + parent.m_selected.getName(). //+ parent.m_item.getName(). replace('.', '_') + "Popup(this.form)"); this.setAttribute("value", "Search"); } @Override public boolean isVisible(PageState ps) { return (!(parent.m_search.isSelected(ps) || parent.m_searchComponent.hasQuery(ps)) && super.isVisible(ps)); } } private class ClearFragment extends Submit { private ItemSearchWidget parent; public ClearFragment(String name, ItemSearchWidget parent) { super(name, GlobalizationUtil.globalize("cms.ui.clear")); this.parent = parent; this.setAttribute("onClick", "this.form." + parent.m_selected.getName() + ".value = \"\";" + "this.form." + parent.m_item.getName() + ".value = \"\";" + "return false;"); this.setAttribute("value", "Clear"); } } private class LabelFragment extends Label { private ItemSearchWidget parent; public LabelFragment(String name, boolean escaping, ItemSearchWidget parent) { super(name, escaping); this.parent = parent; } } private class ItemSearchFragment extends ItemSearchSectionInline { private ItemSearchWidget parent; public ItemSearchFragment(String name, String context, ItemSearchWidget parent, boolean limitToContentSection) { super(name, context, limitToContentSection); this.parent = parent; } public ItemSearchFragment(String name, String context, ItemSearchWidget parent, boolean limitToContentSection, ContentType type) { super(name, context, limitToContentSection, type); this.parent = parent; } @Override public boolean isVisible(PageState ps) { return ((m_search.isSelected(ps) || hasQuery(ps)) && super.isVisible(ps)); } } private class HRLabel extends Label { public HRLabel() { super("
", false); } @Override public boolean isVisible(PageState ps) { return ((m_search.isSelected(ps) || m_searchComponent.hasQuery(ps)) && super.isVisible(ps)); } } /** * Construct a new ItemSearchWidget. The model must be an ItemSearchParameter */ public ItemSearchWidget(ParameterModel model) { this(model, null); } /** * Construct a new ItemSearchWidget. The model must be an ItemSearchParameter * * @param model *param * contentType */ public ItemSearchWidget(final ParameterModel model, final ContentType contentType) { super(new BoxPanel(BoxPanel.VERTICAL)); if (!(model instanceof ItemSearchParameter)) { throw new IllegalArgumentException( "The ItemSearch widget " + model.getName() + " must be backed by a ItemSearchParameter parameter model"); } m_name = model.getName(); m_searchName = m_name + "_search"; m_clearName = m_name + "_clear"; m_model = model; final String typeURLFrag; if (contentType != null) { typeURLFrag = contentType.getID().toString(); } else { typeURLFrag = null; } m_searchModel = new StringParameter(SEARCH); m_contentType = contentType; //m_selected = new Hidden(model); m_selected = new ItemFragment(model, this); final Label selectedItemLabel = new Label(GlobalizationUtil.globalize("" + " cms.ui.item_search.selected")); selectedItemLabel.addPrintListener(new PrintListener() { public void prepare(final PrintEvent event) { final Label target = (Label) event.getTarget(); target.setLabel(GlobalizationUtil.globalize( "cms.ui.item_search.selected")); } }); final Label searchLabel = new Label(searchLabelText); searchLabel.addPrintListener(new PrintListener() { public void prepare(final PrintEvent event) { final Label target = (Label) event.getTarget(); target.setLabel(searchLabelText); } }); //m_item = new ItemFragment(model, this); m_publish = new Hidden(PUBLISH); add(m_publish); m_item = new TextField(m_searchModel); m_search = new SearchFragment(m_searchName, this); m_clear = new ClearFragment(m_clearName, this); m_jsLabel = new LabelFragment("", false, this); m_jsLabel.addPrintListener(new PrintListener() { public void prepare(PrintEvent event) { PageState state = event.getPageState(); Label t = (Label) event.getTarget(); String formName = ((LabelFragment) t).parent.getSearchButton(). getForm().getName(); ParameterMap params = new ParameterMap(); params.setParameter("section_id", CMS.getContext().getContentSection().getID()); params.setParameter("widget", formName + ".elements['" + m_selected. //m_item. getName() + "']"); params.setParameter("searchWidget", formName + ".elements['" + m_item.getName() + "']"); if (typeURLFrag != null) { params.setParameter("single_type", typeURLFrag); } params.setParameter("publishWidget", formName + ".elements['" + m_publish.getName() + "']"); params.setParameter("disableCreatePane", Boolean.toString(disableCreatePane)); params.setParameter("editAfterCreate", Boolean.toString(editAfterCreate)); if (m_defaultCreationFolder != null) { params.setParameter("defaultCreationFolder", m_defaultCreationFolder.getOID().toString()); } if (m_queryField != null) { params.setParameter("queryField", m_queryField); } String searchURL = ContentCenterServlet.getURLStubForClass( ItemSearchPage.class.getName()); s_log.debug("Search URL stub is: " + searchURL); searchURL = ContentCenter.getURL() + searchURL; // TODO Not sure what to do when you get a null here URL url = URL.there(state.getRequest(), searchURL, params); t.setLabel( " "); } }); m_topHR = new HRLabel(); add(m_topHR); final FormSection searchSection = new FormSection(new BoxPanel(BoxPanel.VERTICAL)); final BoxPanel searchRow = new BoxPanel(BoxPanel.HORIZONTAL); searchRow.add(searchLabel); searchRow.add(m_item); searchRow.add(m_search); searchRow.add(m_clear); final BoxPanel itemRow = new BoxPanel(BoxPanel.HORIZONTAL); itemRow.add(selectedItemLabel); itemRow.add(m_selected); searchSection.add(searchRow); searchSection.add(itemRow); searchSection.add(m_jsLabel); add(searchSection); if (m_contentType == null) { m_searchComponent = new ItemSearchFragment(m_name, ContentItem.DRAFT, this, LIMIT_TO_CONTENT_SECTION); } else { m_searchComponent = new ItemSearchFragment(m_name, ContentItem.DRAFT, this, LIMIT_TO_CONTENT_SECTION, m_contentType); } add(m_searchComponent); addSubmissionListener(this); addInitListener(this); m_bottomHR = new HRLabel(); add(m_bottomHR); } @Override public void register(Page p) { super.register(p); p.setVisibleDefault(m_topHR, false); p.setVisibleDefault(m_searchComponent, false); p.setVisibleDefault(m_bottomHR, false); } public ItemSearchWidget(String name) { this(new ItemSearchParameter(name)); } public ItemSearchWidget(String name, String objectType) throws DataObjectNotFoundException { this(name, (objectType == null || objectType.length() == 0 ? null : ContentType.findByAssociatedObjectType(objectType))); } public ItemSearchWidget(String name, ContentType contentType) { this(new ItemSearchParameter(name, contentType), contentType); } public Submit getSearchButton() { return m_search; } public Submit getClearButton() { return m_clear; } public TextField getItemField() { return m_item; } public void init(FormSectionEvent e) throws FormProcessException { PageState s = e.getPageState(); try { m_searchComponent.setVisible(s, false); m_topHR.setVisible(s, false); m_bottomHR.setVisible(s, false); m_search.setVisible(s, true); e.getFormData().put(PUBLISH, Boolean.FALSE.toString()); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } } public void submitted(final FormSectionEvent event) throws FormProcessException { final PageState state = event.getPageState(); final FormData data = event.getFormData(); s_log.debug("Doing submission"); if (m_searchComponent.isItemSelected(state)) { s_log.debug("Item selected"); ContentItem item = m_searchComponent.getSelectedItem(state); if (item != null) { m_item.setValue(state, item); } try { m_searchComponent.setVisible(state, false); m_topHR.setVisible(state, false); m_bottomHR.setVisible(state, false); m_search.setVisible(state, true); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } throw new FormProcessException("item search FormSection submit"); } else if (m_searchComponent.hasQuery(state)) { s_log.debug("Has query"); try { m_searchComponent.setVisible(state, true); m_searchComponent.processQuery(state); m_topHR.setVisible(state, true); m_bottomHR.setVisible(state, true); m_search.setVisible(state, false); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } if (m_contentType != null) { state.setValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM), m_contentType.getID()); } else { state.setValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM), null); } throw new FormProcessException("item search FormSection submit"); } else if (m_search.isSelected(state)) { s_log.debug("Search selected"); try { m_searchComponent.setVisible(state, true); m_searchComponent.processQuery(state); m_topHR.setVisible(state, true); m_bottomHR.setVisible(state, true); m_search.setVisible(state, false); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } if (m_contentType != null) { state.setValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM), m_contentType.getID()); } else { state.setValue(new BigDecimalParameter(ItemSearch.SINGLE_TYPE_PARAM), null); } throw new FormProcessException("item search FormSection submit"); } else if (m_clear.isSelected(state)) { s_log.debug("Clear selected"); m_item.setValue(state, null); try { m_searchComponent.setVisible(state, false); m_topHR.setVisible(state, false); m_bottomHR.setVisible(state, false); m_search.setVisible(state, true); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } throw new FormProcessException("item search FormSection submit"); } else { s_log.debug("Something else"); try { m_searchComponent.setVisible(state, false); m_topHR.setVisible(state, false); m_bottomHR.setVisible(state, false); m_search.setVisible(state, true); } catch (IllegalStateException ex) { // component is in metaform. nothing to do here. Custom generateXML must hide for us } } } public GlobalizedMessage getSearchLabelText() { return searchLabelText; } public void setSearchLabelText(final GlobalizedMessage searchLabelText) { this.searchLabelText = searchLabelText; } public GlobalizedMessage getSelectedLabelText() { return selectedLabelText; } public void setSelectedLabelText(final GlobalizedMessage selectedLabelText) { this.selectedLabelText = selectedLabelText; } public void setDefaultCreationFolder(final Folder folder) { m_defaultCreationFolder = folder; } public void setQueryField(final String queryField) { m_queryField = queryField; } public void publishCreatedItem(final FormData data, final ContentItem item) { final String publishStr = data.getString(ItemSearchWidget.PUBLISH); final Boolean publish = Boolean.valueOf(publishStr); if (publish) { final LifecycleDefinition lifecycleDef = ContentTypeLifecycleDefinition.getLifecycleDefinition( item.getContentSection(), item.getContentType()); if (lifecycleDef == null) { s_log.warn(String.format("Cannot publish item %s because it has no default lifecycle", item.getOID().toString())); } else { item.publish(lifecycleDef, new Date()); item.getLifecycle().start(); final Workflow workflow = Workflow.getObjectWorkflow(item); if (workflow != null) { workflow.delete(); } } } } public boolean getDisableCreatePane() { return disableCreatePane; } public void setDisableCreatePane(final boolean disableCreatePane) { this.disableCreatePane = disableCreatePane; } public void setEditAfterCreate(final boolean editAfterCreate) { this.editAfterCreate = editAfterCreate; } }