/** * Copyright (c) 2009 Juwi MacMillan Group GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.juwimm.cms.content.panel; import static de.juwimm.cms.client.beans.Application.getBean; import static de.juwimm.cms.common.Constants.rb; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JSplitPane; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.apache.log4j.Logger; import org.tizzit.util.XercesHelper; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import de.juwimm.cms.client.beans.Application; import de.juwimm.cms.client.beans.Beans; import de.juwimm.cms.content.ContentManager; import de.juwimm.cms.content.modules.Teaser; import de.juwimm.cms.content.modules.Teaser.TeaserProperties; import de.juwimm.cms.search.vo.XmlSearchValue; import de.juwimm.cms.util.Communication; import de.juwimm.cms.util.UIConstants; import de.juwimm.swing.AbstractPickListModel; import de.juwimm.swing.DropDownHolder; import de.juwimm.swing.PickListData; import de.juwimm.swing.PickListPanel; import de.juwimm.swing.SortableListModel; /** * The panel for displaying the teaser within the client. * * @author <a href="mailto:christiane.hausleiter@juwimm.com">Christiane Hausleiter</a> * */ @SuppressWarnings("serial") public class PanTeaser extends JPanel { private Communication communication; private final Logger log = Logger.getLogger(PanTeaser.class); private final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); private JPanel pnlDefinedTeaser; private JPanel pnlHeaderLeft; private PickListPanel pickListPanel; private JPanel pnlRandomTeaser; private JPanel pnlHeaderRight; private JPanel pnlRandomChoice; private final Dimension minDefinedTeaserDim = new Dimension(250, 210); private final Dimension prefDefinedTeaserDim = new Dimension(280, 250); private final Dimension maxDefinedTeaserDim = new Dimension(800, 600); private final Dimension minRandomTeaserDim = new Dimension(100, 210); private final Dimension prefRandomTeaserDim = new Dimension(170, 250); private final Dimension maxRandomTeaserDim = new Dimension(800, 600); private ButtonGroup buttonGroup; private PickListData pickListData; private String currentSearchScope; private boolean isInitialized = false; /** All search scopes (defined by the dcfConfig for this mandator). */ private final ArrayList<String> searchScopes = new ArrayList<String>(); /** All {@link JRadioButton}s that are displayed for the available search scopes. * Each JRadioButton has an {@code ActionCommand} named after the search scope the JRadioButton represents. */ private final ArrayList<JRadioButton> radioButtonList = new ArrayList<JRadioButton>(); /** All random teaser's {@link JComboBox}es that are displayed for the available search scopes */ private final ArrayList<JComboBox> comboBoxList = new ArrayList<JComboBox>(); /** A container for all teaser properties (defined by the dcfConfig's {@code <properties>} element for this mandator). */ private final Hashtable<String, Teaser.TeaserProperties> hshTeaserProps = new Hashtable<String, Teaser.TeaserProperties>(); /** * Default constructor. */ public PanTeaser() { try { this.setLayout(new BorderLayout()); ArrayList<String> dummySearchScopes = new ArrayList<String>(); this.communication = ((Communication) getBean(Beans.COMMUNICATION)); Dimension headerDim = new Dimension(40, 60); Dimension comboDim = new Dimension(130, 20); // ********************************************************** // Left: Explicitly chosen teaser // ********************************************************** this.pnlHeaderLeft = new JPanel(); this.buttonGroup = new ButtonGroup(); JLabel lblFixedTeaser = new JLabel(rb.getString("content.modules.teaser.fixed.text")); this.pnlHeaderLeft.add(lblFixedTeaser); for (int i = 0, count = dummySearchScopes.size(); i < count; i++) { final String searchScope = dummySearchScopes.get(i); JRadioButton btnRadio = new JRadioButton(searchScope, false); btnRadio.setActionCommand(searchScope); btnRadio.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if (!evt.getActionCommand().equals(currentSearchScope)) { searchTeasersForScope(); } } }); btnRadio.setBorderPainted(false); btnRadio.setOpaque(false); this.buttonGroup.add(btnRadio); this.pnlHeaderLeft.add(btnRadio); } this.pnlHeaderLeft.setPreferredSize(headerDim); this.pnlHeaderLeft.setMinimumSize(headerDim); this.pnlHeaderLeft.setBorder(new CompoundBorder(new EmptyBorder(5, 5, 5, 5), new TitledBorder(rb.getString("content.modules.teaser.fixed.title")))); this.pickListData = new PickListData(new SortableListModel(), new SortableListModel()); this.pickListData.setLeftLabel(rb.getString("content.modules.teaser.added.teaser")); this.pickListData.setRightLabel(rb.getString("content.modules.teaser.available.teaser")); this.pickListPanel = new PickListPanel(this.pickListData, true); this.pnlDefinedTeaser = new JPanel(); this.pnlDefinedTeaser.setLayout(new BorderLayout()); this.pnlDefinedTeaser.setMinimumSize(this.minDefinedTeaserDim); this.pnlDefinedTeaser.setPreferredSize(this.prefDefinedTeaserDim); this.pnlDefinedTeaser.setMaximumSize(this.maxDefinedTeaserDim); this.pnlDefinedTeaser.setOpaque(true); // ********************************************************** // Right: Random teaser // ********************************************************** JLabel lblRandomTeaser = new JLabel(rb.getString("content.modules.teaser.random.text")); this.pnlHeaderRight = new JPanel(); this.pnlHeaderRight.setPreferredSize(headerDim); this.pnlHeaderRight.setMinimumSize(headerDim); this.pnlHeaderRight.add(lblRandomTeaser); this.pnlHeaderRight.setBorder(new CompoundBorder(new EmptyBorder(5, 5, 5, 5), new TitledBorder(rb.getString("content.modules.teaser.random.title")))); this.pnlRandomChoice = new JPanel(); this.pnlRandomChoice.setLayout(new BoxLayout(this.pnlRandomChoice, BoxLayout.Y_AXIS)); for (int i = 0, count = dummySearchScopes.size(); i < count; i++) { this.pnlRandomChoice.add(Box.createRigidArea(new Dimension(0, 5))); JPanel pnlContainer = new JPanel(); pnlContainer.setMaximumSize(comboDim); pnlContainer.setLayout(new GridLayout(0, 2)); JLabel lblSearchScope = new JLabel(dummySearchScopes.get(i)); JComboBox cbox = new JComboBox(buildComboBoxModel(5)); cbox.setName(dummySearchScopes.get(i)); this.comboBoxList.add(cbox); cbox.setPreferredSize(comboDim); cbox.setMaximumSize(comboDim); pnlContainer.add(lblSearchScope); pnlContainer.add(cbox); this.pnlRandomChoice.add(pnlContainer); } this.pnlRandomTeaser = new JPanel(); this.pnlRandomTeaser.setLayout(new BorderLayout()); this.pnlRandomTeaser.setMinimumSize(this.minRandomTeaserDim); this.pnlRandomTeaser.setPreferredSize(this.prefRandomTeaserDim); this.pnlRandomTeaser.setMaximumSize(this.maxRandomTeaserDim); this.pnlRandomTeaser.setOpaque(true); this.pnlHeaderLeft.setBackground(UIConstants.backgroundBaseColor); this.pnlHeaderRight.setBackground(UIConstants.backgroundBaseColor); this.pnlDefinedTeaser.add(this.pnlHeaderLeft, BorderLayout.NORTH); this.pnlDefinedTeaser.add(this.pickListPanel, BorderLayout.CENTER); this.pnlRandomTeaser.add(this.pnlHeaderRight, BorderLayout.NORTH); this.pnlRandomTeaser.add(this.pnlRandomChoice, BorderLayout.CENTER); this.splitPane.setLeftComponent(this.pnlDefinedTeaser); this.splitPane.setRightComponent(this.pnlRandomTeaser); this.splitPane.setOneTouchExpandable(true); this.splitPane.setResizeWeight(1.0); this.add(this.splitPane, BorderLayout.CENTER); } catch (Exception exception) { log.error("Initialization error", exception); } } /** * Adds the specified {@link TeaserProperties} to the list of managed teasers. * * @param name the properties' name * @param teaserProperties the {@code TeaserProperties} to add */ public void addSearchScope(String name, Teaser.TeaserProperties teaserProperties) { String unit = teaserProperties.getUnit(); if (!this.searchScopes.contains(unit)) { this.searchScopes.add(unit); } this.hshTeaserProps.put(name, teaserProperties); } /** * Re-initializes this panel's view. This should be called after all possible search scopes were added. * Creates the radio buttons that enable the user to change search scopes (as defined by this mandator's dcfConfig). * Creates the drop down boxes that enable the user to choose randomized teasers. */ public void reInitialize() { Dimension comboDim = new Dimension(130, 20); this.radioButtonList.clear(); this.comboBoxList.clear(); this.pnlHeaderLeft.removeAll(); this.pnlRandomChoice.removeAll(); this.buttonGroup = new ButtonGroup(); JLabel lblFixedTeaser = new JLabel(rb.getString("content.modules.teaser.fixed.text")); this.pnlHeaderLeft.add(lblFixedTeaser); // ********************************************************** // Left: Explicitly chosen teaser // ********************************************************** for (int i = 0, count = searchScopes.size(); i < count; i++) { final String searchScope = this.searchScopes.get(i); JRadioButton btnRadio = new JRadioButton(searchScope, false); btnRadio.setActionCommand(searchScope); btnRadio.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { currentSearchScope = searchScope; searchTeasersForScope(); } }); btnRadio.setBorderPainted(false); btnRadio.setOpaque(false); this.buttonGroup.add(btnRadio); this.pnlHeaderLeft.add(btnRadio); this.radioButtonList.add(btnRadio); } for (int i = 0, count = this.radioButtonList.size(); i < count; i++) { if (this.radioButtonList.get(i).isSelected()) { this.currentSearchScope = radioButtonList.get(i).getActionCommand(); break; } } // ********************************************************** // Right: Random teaser // ********************************************************** for (int i = 0, count = this.searchScopes.size(); i < count; i++) { this.pnlRandomChoice.add(Box.createRigidArea(new Dimension(0, 10))); String currentSearchScope = this.searchScopes.get(i); int maxRandomTeasersForScope = getRandomizableTeaserCount(currentSearchScope); JPanel pnlContainer = new JPanel(); pnlContainer.setMaximumSize(comboDim); pnlContainer.setLayout(new GridLayout(0, 2)); JLabel lblSearchScope = new JLabel(currentSearchScope); JComboBox cbox = new JComboBox(buildComboBoxModel(maxRandomTeasersForScope)); cbox.setName(this.searchScopes.get(i)); this.comboBoxList.add(cbox); cbox.setPreferredSize(comboDim); cbox.setMaximumSize(comboDim); pnlContainer.add(lblSearchScope); pnlContainer.add(cbox); this.pnlRandomChoice.add(pnlContainer); } this.splitPane.resetToPreferredSizes(); this.validate(); this.isInitialized = true; reset(); } /** * Unloads the current search scope and removes all elements from the pick list panel. */ private void reset() { this.currentSearchScope = null; this.pickListData.getLstLeftModel().removeAllElements(); this.pickListData.getLstRightModel().removeAllElements(); } /** * Selects the radio button for the current search scope, * calls the search for the available teasers, * and sets the maximum values for the random teaser's combo boxes. */ public void set() { if (this.searchScopes.contains(Teaser.SCOPE_THIS)) { this.currentSearchScope = Teaser.SCOPE_THIS; } else if (this.searchScopes.contains(Teaser.SCOPE_PARENT)) { this.currentSearchScope = Teaser.SCOPE_PARENT; } else if (this.searchScopes.contains(Teaser.SCOPE_ROOT)) { this.currentSearchScope = Teaser.SCOPE_ROOT; } else { this.currentSearchScope = Teaser.SCOPE_SITE; } for (int i = 0, count = this.radioButtonList.size(); i < count; i++) { if (this.radioButtonList.get(i).getActionCommand().equals(this.currentSearchScope)) { this.radioButtonList.get(i).setSelected(true); this.searchTeasersForScope(); break; } } for (int i = 0, count = this.comboBoxList.size(); i < count; i++) { // max value JComboBox jcb = this.comboBoxList.get(i); int maxCount = getRandomizableTeaserCount(jcb.getName()); jcb.setModel(buildComboBoxModel(maxCount + 1)); } } /** * Is called each time this teaser panel is displayed within the client. * * @param node */ public void setProperties(Node node) { if (log.isDebugEnabled()) { log.debug("setProperties() called with node: " + (node == null ? "null" : node.getNodeName())); } if (!this.isInitialized) { reInitialize(); } reset(); if (node != null) { set(); // Random teaser: Iterator randomRefIterator = XercesHelper.findNodes(node, "./teaserRandomized"); while (randomRefIterator.hasNext()) { Element elmRandomTeaser = (Element) randomRefIterator.next(); int count = 0; String countString = ""; String searchScope = ""; try { searchScope = XercesHelper.findNode(elmRandomTeaser, "./unit").getFirstChild().getNodeValue(); countString = XercesHelper.findNode(elmRandomTeaser, "./count").getFirstChild().getNodeValue(); } catch (Exception exception) { log.error(exception.getMessage(), exception); } if (searchScope.length() > 0) { try { count = Integer.parseInt(countString); } catch (NumberFormatException exception) { log.error("Error parsing String to int: " + countString); } } // die ComboBoxen auf die gespeicherten Werte setzen for (int i = 0, maxI = this.comboBoxList.size(); i < maxI; i++) { if (this.comboBoxList.get(i).getName().equals(searchScope)) { JComboBox comboBoxToSet = this.comboBoxList.get(i); if (count < comboBoxToSet.getItemCount()) { comboBoxToSet.getModel().setSelectedItem(comboBoxToSet.getItemAt(count)); } else { comboBoxToSet.getModel().setSelectedItem(comboBoxToSet.getItemAt(comboBoxToSet.getItemCount() - 1)); } } } } Iterator refIterator = XercesHelper.findNodes(node, "./teaserRef"); while (refIterator.hasNext()) { Element elmTeaser = (Element) refIterator.next(); String referencedComponentIdString = elmTeaser.getAttribute("viewComponentId"); String xpathTeaserElement = elmTeaser.getAttribute("xpathTeaserElement"); String teaserName = elmTeaser.getAttribute("teaserName"); String xpathIdentifier = elmTeaser.getAttribute("xpathTeaserIdentifier"); if (xpathIdentifier.length() == 0) { xpathIdentifier = null; } String idString = elmTeaser.getAttribute("teaserIdentifier"); if (idString.length() == 0) { idString = null; } String xpathTeaserName = elmTeaser.getAttribute("xpathTeaserName"); if (xpathTeaserName.length() == 0) { xpathTeaserName = null; } try { int referencedComponentId = Integer.parseInt(referencedComponentIdString); TeaserValue teaserValue = new TeaserValue(referencedComponentId, teaserName, xpathTeaserElement, xpathTeaserName, xpathIdentifier, idString); this.chooseTeaser(teaserValue); } catch (NumberFormatException exception) { log.error("Error parsing teaser's component id: " + referencedComponentIdString, exception); } } } } public Node getProperties() { Node teaserIncludeNode = ContentManager.getDomDoc().createElement("teaserInclude"); AbstractPickListModel selectedTeasers = this.pickListData.getLstLeftModel(); for (int i = 0, count = selectedTeasers.getSize(); i < count; i++) { Element elmTeaser = ContentManager.getDomDoc().createElement("teaserRef"); TeaserValue teaserValue = (TeaserValue) ((DropDownHolder) selectedTeasers.getElementAt(i)).getObject(); // mandatory attribute Attr attrViewComponentId = ContentManager.getDomDoc().createAttribute("viewComponentId"); attrViewComponentId.setValue(Integer.toString(teaserValue.getViewComponentId())); elmTeaser.setAttributeNode(attrViewComponentId); // mandatory attribute Attr attrXpathTeaserElement = ContentManager.getDomDoc().createAttribute("xpathTeaserElement"); attrXpathTeaserElement.setValue(teaserValue.getXpathTeaserElement()); elmTeaser.setAttributeNode(attrXpathTeaserElement); // mandatory attribute Attr attrTeaserName = ContentManager.getDomDoc().createAttribute("teaserName"); attrTeaserName.setValue(teaserValue.getTeaserName()); elmTeaser.setAttributeNode(attrTeaserName); if (teaserValue.getTeaserIdentifier() != null) { Attr attrTeaserIdentifier = ContentManager.getDomDoc().createAttribute("teaserIdentifier"); attrTeaserIdentifier.setValue(teaserValue.getTeaserIdentifier()); elmTeaser.setAttributeNode(attrTeaserIdentifier); } if (teaserValue.getXpathTeaserIdentifier() != null) { Attr attrXpathTeaserIdentifier = ContentManager.getDomDoc().createAttribute("xpathTeaserIdentifier"); attrXpathTeaserIdentifier.setValue(teaserValue.getXpathTeaserIdentifier()); elmTeaser.setAttributeNode(attrXpathTeaserIdentifier); } teaserIncludeNode.appendChild(elmTeaser); } for (int i = 0, count = this.comboBoxList.size(); i < count; i++) { int chosenValue = ((Integer) ((DropDownHolder) this.comboBoxList.get(i).getModel().getSelectedItem()).getObject()).intValue(); if (chosenValue > 0) { JComboBox comboBox = this.comboBoxList.get(i); String comboBoxName = comboBox.getName(); // name = search scope TeaserValue teaserValue = (TeaserValue) ((DropDownHolder) selectedTeasers.getElementAt(i)).getObject(); String xpathTeaserElement = null; Enumeration teaserPropsEnumeration = this.hshTeaserProps.elements(); while (teaserPropsEnumeration.hasMoreElements()) { Teaser.TeaserProperties currentTeaserProps = (Teaser.TeaserProperties) teaserPropsEnumeration.nextElement(); if (currentTeaserProps.getUnit().equals(comboBoxName) && currentTeaserProps.getRandomizable().booleanValue()) { xpathTeaserElement = currentTeaserProps.getXpathTeaserElement(); } } if (xpathTeaserElement == null) { if (log.isDebugEnabled()) { log.debug("Could not find xpathTeaserElement for " + comboBoxName + "'s randomized teaser"); } continue; } Element elmRandomTeaser = ContentManager.getDomDoc().createElement("teaserRandomized"); // mandatory attribute Attr attrViewComponentId = ContentManager.getDomDoc().createAttribute("viewComponentId"); attrViewComponentId.setValue(Integer.toString(teaserValue.getViewComponentId())); elmRandomTeaser.setAttributeNode(attrViewComponentId); Attr attrXPath = ContentManager.getDomDoc().createAttribute("xpathTeaserElement"); attrXPath.setValue(xpathTeaserElement); elmRandomTeaser.setAttributeNode(attrXPath); Attr attrRandomCount = ContentManager.getDomDoc().createAttribute("count"); attrRandomCount.setValue(Integer.toString(chosenValue)); elmRandomTeaser.setAttributeNode(attrRandomCount); Attr attrUnit = ContentManager.getDomDoc().createAttribute("unit"); attrUnit.setValue(comboBox.getName()); elmRandomTeaser.appendChild(attrUnit); teaserIncludeNode.appendChild(elmRandomTeaser); } } return teaserIncludeNode; } /** @see java.awt.Component#isModuleValid() */ public boolean isModuleValid() { return true; } public String validateSelectedTeasers(boolean isMandatory) { long startTime = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Start validateSelectedTeasers()"); } boolean isValid = true; // Hashtable: key = xpathTeaserElement (z.B. "//teaser"), value = ArrayList<TeaserValue> die das key-xpathTeaserElement beinhalten Hashtable<String, ArrayList<TeaserValue>> referencedTeasers = new Hashtable<String, ArrayList<TeaserValue>>(); AbstractPickListModel selectedTeasers = this.pickListData.getLstLeftModel(); if (isMandatory) { if (selectedTeasers == null || selectedTeasers.getSize() == 0) { return rb.getString("exception.TeaserRequired"); } } for (int i = 0, count = selectedTeasers.getSize(); i < count; i++) { TeaserValue teaserValue = (TeaserValue) ((DropDownHolder) selectedTeasers.getElementAt(i)).getObject(); String xpathTeaserElement = teaserValue.getXpathTeaserElement(); ArrayList<TeaserValue> arrayListTeaserValues = referencedTeasers.get(xpathTeaserElement) == null ? new ArrayList<TeaserValue>() : referencedTeasers.get(xpathTeaserElement); arrayListTeaserValues.add(teaserValue); referencedTeasers.put(xpathTeaserElement, arrayListTeaserValues); } // Check if referenced teasers still exist: try { Enumeration keyEnumeration = referencedTeasers.keys(); if (referencedTeasers.isEmpty()) { return null; } StringBuilder invalidTeasers = new StringBuilder(); while (keyEnumeration.hasMoreElements()) { String xpathString = (String) keyEnumeration.nextElement(); ArrayList<TeaserValue> arrayListReferencedTeasers = referencedTeasers.get(xpathString); // Start search (just once per xpath term!) XmlSearchValue[] xmlSearchValuesAllTeaserForXpath = this.communication.searchXml(this.communication.getSiteId(), xpathString); // outer loop: all referenced teasers for (int i = 0, count = arrayListReferencedTeasers.size(); i < count; i++) { boolean referencedTeaserExists = false; TeaserValue refTeaser = arrayListReferencedTeasers.get(i); // inner loop: all found teasers for the xpath term for (int j = 0; j < xmlSearchValuesAllTeaserForXpath.length; j++) { if (refTeaser.getViewComponentId() == xmlSearchValuesAllTeaserForXpath[j].getViewComponentId()) { if (refTeaser.getXpathTeaserIdentifier() != null) { if (refTeaser.getTeaserIdentifier() != null) { ArrayList<TeaserValue> resultList = createTeaserValueListFromXml(xmlSearchValuesAllTeaserForXpath[j], xpathString, refTeaser.getXpathTeaserIdentifier(), refTeaser.getXpathTeaserName()); for (int k = 0; k < resultList.size(); k++) { if (resultList.get(k).getTeaserIdentifier() != null && resultList.get(k).getTeaserIdentifier().equals(refTeaser.getTeaserIdentifier())) { referencedTeaserExists = true; break; // inner loop } } } else { log.error("XPath for teaser identifier specified but no teaser identifier itself!"); } } // if no xpath term was specified for teaserIdentifier, matching the viewComponentId is enough: else { referencedTeaserExists = true; } if (referencedTeaserExists) { break; // outer loop } } } if (!referencedTeaserExists) { invalidTeasers.append("\n" + refTeaser.getTeaserName()); } isValid = isValid ? referencedTeaserExists : false; } } if (!isValid) { invalidTeasers.insert(0, rb.getString("content.modules.teaser.invalid")); long milliseconds = System.currentTimeMillis() - startTime; if (log.isDebugEnabled()) { log.debug("Finished validateSelectedTeasers(): Calculation took " + milliseconds + " milliseconds"); } return invalidTeasers.toString(); } } catch (Exception exception) { log.error(exception); } long milliseconds = System.currentTimeMillis() - startTime; if (log.isDebugEnabled()) { log.debug("Finished validateSelectedTeasers(): Calculation took " + milliseconds + " milliseconds"); } return null; } @Override public void setEnabled(boolean enabling) { super.setEnabled(enabling); this.splitPane.setOneTouchExpandable(enabling); this.splitPane.setEnabled(enabling); this.pickListPanel.setEnabled(enabling); for (JRadioButton radioButton : this.radioButtonList) { radioButton.setEnabled(enabling); } for (JComboBox comboBox : this.comboBoxList) { comboBox.setEnabled(enabling); } } private DefaultComboBoxModel buildComboBoxModel(int maxCount) { DropDownHolder[] dropDownHolderArray = new DropDownHolder[maxCount]; for (int i = 0; i < maxCount; i++) { dropDownHolderArray[i] = new DropDownHolder(new Integer(i), Integer.toString(i)); } return new DefaultComboBoxModel(dropDownHolderArray); } private int getRandomizableTeaserCount(String searchScope) { int result = 0; int unitId = -666; boolean parentSearch = false; boolean siteSearch = false; ContentManager contentManager = (ContentManager) Application.getBean(Beans.CONTENT_MANAGER); if (searchScope.equals(Teaser.SCOPE_THIS)) { unitId = contentManager.getActUnitId(); } else if (searchScope.equals(Teaser.SCOPE_ROOT)) { // TODO if root.unitId == this.unitId the searching can be stopped unitId = contentManager.getRootUnitId(); } else if (searchScope.equals(Teaser.SCOPE_PARENT)) { unitId = contentManager.getActUnitId(); parentSearch = true; } else if (searchScope.equals(Teaser.SCOPE_SITE)) { unitId = 0; siteSearch = true; } if (unitId != -666) { // all teaserProperties for the specific SearchScope ArrayList<Teaser.TeaserProperties> randomizableTeaserPropsForScope = new ArrayList<TeaserProperties>(); Enumeration teaserPropsEnumeration = this.hshTeaserProps.elements(); while (teaserPropsEnumeration.hasMoreElements()) { Teaser.TeaserProperties currentTeaserProps = (Teaser.TeaserProperties) teaserPropsEnumeration.nextElement(); if (currentTeaserProps.getUnit().equals(searchScope) && currentTeaserProps.getRandomizable().booleanValue()) { randomizableTeaserPropsForScope.add(currentTeaserProps); } } if (!randomizableTeaserPropsForScope.isEmpty()) { for (int i = 0, count = randomizableTeaserPropsForScope.size(); i < count; i++) { String xPath = randomizableTeaserPropsForScope.get(i).getXpathTeaserElement(); XmlSearchValue[] searchResult = null; try { if (siteSearch) { searchResult = this.communication.searchXml(this.communication.getSiteId(), xPath); } else { searchResult = this.communication.searchXmlByUnit(unitId, xPath, parentSearch); } if (searchResult != null) { for (int j = 0; j < searchResult.length; j++) { String resultRootStartElement = "<searchTeaserResult>"; String resultRootEndElement = "</searchTeaserResult>"; String lastElementSearchedFor = xPath.substring(xPath.lastIndexOf('/'), xPath.length()); StringBuilder stringBuilder = new StringBuilder(searchResult[j].getContent()); stringBuilder.insert(0, resultRootStartElement); stringBuilder.append(resultRootEndElement); Document doc = XercesHelper.string2Dom(stringBuilder.toString()); Iterator teaserIterator = XercesHelper.findNodes(doc, "searchTeaserResult" + lastElementSearchedFor); while (teaserIterator.hasNext()) { teaserIterator.next(); result++; } } } } catch (Exception exception) { String searchFunction = siteSearch ? "searchXml(siteId, xPath)" : "searchXmlByUnit(unitId, xPath)"; log.error("An error occurred executing " + searchFunction + ": ", exception); } } } } return result; } /** * Searches for teasers belonging to {@code this.currentSearchScope}. * This method should only be called when the currentSearchScope did change. */ private void searchTeasersForScope() { try { int unitId = -666; boolean parentSearch = false; boolean siteSearch = false; ContentManager contentManager = (ContentManager) Application.getBean(Beans.CONTENT_MANAGER); if (this.currentSearchScope.equals(Teaser.SCOPE_THIS)) { unitId = contentManager.getActUnitId(); } else if (this.currentSearchScope.equals(Teaser.SCOPE_ROOT)) { unitId = contentManager.getRootUnitId(); } else if (this.currentSearchScope.equals(Teaser.SCOPE_PARENT)) { unitId = contentManager.getActUnitId(); parentSearch = true; } else if (this.currentSearchScope.equals(Teaser.SCOPE_SITE)) { unitId = 0; siteSearch = true; } if (unitId != -666) { if (log.isDebugEnabled()) { log.debug("searchTeasersForScope() unitId = " + unitId); } // delete all existing teasers for the old search scope this.pickListData.getLstRightModel().removeAllElements(); // all teaserProperties for current search scope ArrayList<Teaser.TeaserProperties> teaserPropsForScope = new ArrayList<TeaserProperties>(); Enumeration teaserPropsEnumeration = this.hshTeaserProps.elements(); while (teaserPropsEnumeration.hasMoreElements()) { Teaser.TeaserProperties currentTeaserProps = (Teaser.TeaserProperties) teaserPropsEnumeration.nextElement(); if (currentTeaserProps.getUnit().equals(this.currentSearchScope)) { teaserPropsForScope.add(currentTeaserProps); } } if (!teaserPropsForScope.isEmpty()) { for (int i = 0, count = teaserPropsForScope.size(); i < count; i++) { TeaserProperties props = teaserPropsForScope.get(i); String xPath = props.getXpathTeaserElement(); String xPathIdentifier = props.getXpathTeaserIdentifier(); String xPathTeaserName = props.getXpathTeaserName(); XmlSearchValue[] searchResult = null; if (siteSearch) { searchResult = this.communication.searchXml(this.communication.getSiteId(), xPath); } else { searchResult = this.communication.searchXmlByUnit(unitId, xPath, parentSearch); } if (searchResult != null) { for (int j = 0; j < searchResult.length; j++) { ArrayList<TeaserValue> teaserValueList = createTeaserValueListFromXml(searchResult[j], xPath, xPathIdentifier, xPathTeaserName); for (int k = 0; k < teaserValueList.size(); k++) { TeaserValue teaserValue = teaserValueList.get(k); boolean teaserAlreadyChosen = false; Iterator chosenIterator = this.pickListData.getLstLeftModel().iterator(); while (chosenIterator.hasNext()) { DropDownHolder ddh = (DropDownHolder) chosenIterator.next(); TeaserValue chosenTeaserValue = (TeaserValue) ddh.getObject(); if (teaserValue.getViewComponentId() == chosenTeaserValue.getViewComponentId()) { if (teaserValue.getTeaserIdentifier() != null) { if (teaserValue.getTeaserIdentifier().equals(chosenTeaserValue.getTeaserIdentifier())) { teaserAlreadyChosen = true; } } else { if (chosenTeaserValue.teaserIdentifier == null) { teaserAlreadyChosen = true; } } } } if (!teaserAlreadyChosen) { DropDownHolder dropDownHolder = new DropDownHolder(teaserValue, teaserValue.getTeaserName()); this.pickListData.getLstRightModel().addElement(dropDownHolder); } this.pickListData.setModified(true); this.validate(); this.repaint(); } } } } } } } catch (Exception exception) { log.error(exception); } } private ArrayList<TeaserValue> createTeaserValueListFromXml(XmlSearchValue xmlSearchValue, String xpathTeaserElement, String xpathIdentifier, String xpathTeaserName) { ArrayList<TeaserValue> result = new ArrayList<TeaserValue>(); if (xmlSearchValue != null) { try { String resultRootStartElement = "<searchTeaserResult>"; String resultRootEndElement = "</searchTeaserResult>"; String lastElementSearchedFor = xpathTeaserElement.substring(xpathTeaserElement.lastIndexOf('/'), xpathTeaserElement.length()); StringBuilder stringBuilder = new StringBuilder(xmlSearchValue.getContent()); stringBuilder.insert(0, resultRootStartElement); stringBuilder.append(resultRootEndElement); Document doc = XercesHelper.string2Dom(stringBuilder.toString()); Iterator teaserIterator = XercesHelper.findNodes(doc, "/" + lastElementSearchedFor); String identifierValue = null; String teaserNameValue = null; while (teaserIterator.hasNext()) { Node node = (Node) teaserIterator.next(); if (xpathIdentifier != null) { if (xpathIdentifier.contains("@")) { // look for attribute if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; int atIndex = xpathTeaserName.indexOf("@") + 1; identifierValue = element.getAttribute(xpathIdentifier.substring(atIndex)); } else { log.error("Node " + node.getNodeName() + " should contain attribute " + xpathIdentifier + " - but is no element node"); } } else { // look for child element Node identifierNode = XercesHelper.findNode(node, xpathIdentifier); if (identifierNode != null) { identifierValue = identifierNode.getFirstChild().getNodeValue(); } else { log.error("Node " + node.getNodeName() + " should contain element " + xpathIdentifier + " but it does not"); } } } if (xpathTeaserName == null) { // if dcf does not define neither an attribute nor an element for specifying the teaser's name teaserNameValue = xmlSearchValue.getText(); teaserNameValue = teaserNameValue.replaceAll("ä", "ae"); teaserNameValue = teaserNameValue.replaceAll("ö", "oe"); teaserNameValue = teaserNameValue.replaceAll("ü", "ue"); teaserNameValue = teaserNameValue.replaceAll("Ä", "Ae"); teaserNameValue = teaserNameValue.replaceAll("Ö", "Oe"); teaserNameValue = teaserNameValue.replaceAll("Ü", "Ue"); teaserNameValue = teaserNameValue.replaceAll("ß", "ss"); teaserNameValue.replaceAll("[^A-Za-z_0-9\\.-]", ""); } else { if (xpathTeaserName.contains("@")) { // look for attribute if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; int atIndex = xpathTeaserName.indexOf("@") + 1; teaserNameValue = element.getAttribute(xpathTeaserName.substring(atIndex)); } else { log.error("Node " + node.getNodeName() + " should contain attribute " + xpathTeaserName + " - but is no element node"); } } else { // look for child element Node identifierNode = XercesHelper.findNode(node, xpathTeaserName); if (identifierNode != null) { identifierValue = identifierNode.getFirstChild().getNodeValue(); } else { log.error("Node " + node.getNodeName() + " should contain element " + xpathTeaserName + " but it does not"); } } } result.add(new TeaserValue(xmlSearchValue.getViewComponentId(), teaserNameValue, xpathTeaserElement, xpathTeaserName, xpathIdentifier, identifierValue)); } } catch (Exception exception) { log.error(exception.getMessage(), exception); } } return result; } /** * Adds the specified {@link TeaserValue} to the pick list panel's "chosen"-side. * The teaser needs not necessarily being mentioned on the pick list panel's "available"-side, * but if it is, it will be removed from there. * * @param teaserValue the {@code TeaserValue} to add */ private void chooseTeaser(TeaserValue teaserValue) { // if chosen teaserRef is inside the pool of choosable teasers: take it from there Iterator availableIterator = this.pickListData.getLstRightModel().iterator(); boolean foundInAvailables = false; while (availableIterator.hasNext()) { DropDownHolder availableObject = (DropDownHolder) availableIterator.next(); TeaserValue availableTeaserValue = (TeaserValue) availableObject.getObject(); if (availableTeaserValue.getViewComponentId() == teaserValue.getViewComponentId()) { boolean teaserFound = true; // more than one teaser per component? if (teaserValue.teaserIdentifier != null) { if (!teaserValue.teaserIdentifier.equals(availableTeaserValue.teaserIdentifier)) { teaserFound = false; } } if (teaserFound) { this.pickListData.getLstRightModel().removeElement(availableObject); this.pickListData.getLstLeftModel().addElement(availableObject); } foundInAvailables = teaserFound; } } // if chosen teaserRef is not part of the list of choosable teasers: create new element if (!foundInAvailables) { DropDownHolder ddh = new DropDownHolder(teaserValue, teaserValue.getTeaserName()); this.pickListData.getLstLeftModel().addElement(ddh); } } /** * Type for holding Teaser references (may be wrapped by a {@link DropDownHolder}). * This type is used for displaying teasers inside the pick list panel. * * @author <a href="mailto:christiane.hausleiter@juwimm.com">Christiane Hausleiter</a> * */ public class TeaserValue { private final int viewComponentId; private final String teaserName; private final String xpathTeaserName; private final String teaserIdentifier; private final String xpathTeaserElement; private final String xpathTeaserIdentifier; /** * Value constructor. * * @param viewComponentId the component's ID that contains the teaser * @param teaserName the component's name * @param xpathTeaserElement the xpath term for finding the teaser * @param xpathTeaserName the xpath term for the teaser's name (headline) * @param xpathTeaserIdentifier the xpath term for identifiying a teaser within multiple teaser elements * @param teaserIdentifier the value identifiying the teaser within multiple teaser elements */ public TeaserValue(int viewComponentId, String teaserName, String xpathTeaserElement, String xpathTeaserName, String xpathTeaserIdentifier, String teaserIdentifier) { this.viewComponentId = viewComponentId; this.teaserName = teaserName; this.xpathTeaserName = xpathTeaserName; this.teaserIdentifier = teaserIdentifier; this.xpathTeaserElement = xpathTeaserElement; this.xpathTeaserIdentifier = xpathTeaserIdentifier; } /** * @return the teaserIdentifier */ public String getTeaserIdentifier() { return teaserIdentifier; } /** * @return the viewComponentId */ public int getViewComponentId() { return viewComponentId; } /** * @return the xpathTeaserName */ public String getXpathTeaserName() { return xpathTeaserName; } /** * @return the xpathTeaserElement */ public String getXpathTeaserElement() { return xpathTeaserElement; } /** * @return the xpathTeaserIdentifier */ public String getXpathTeaserIdentifier() { return xpathTeaserIdentifier; } /** * @return the teaserName */ public String getTeaserName() { return teaserName; } } }