- Localisation for Search (ResultsPane), Ticket #1762

- Some formating


git-svn-id: https://svn.libreccm.org/ccm/trunk@2553 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2014-03-04 18:35:21 +00:00
parent ef8618fad2
commit c21769dfc8
15 changed files with 490 additions and 353 deletions

View File

@ -1068,3 +1068,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of
cms.ui.search.help=To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.
cms.ui.search.no_results=Sorry. Not content items found which match your search.

View File

@ -1062,3 +1062,5 @@ cms.ui.move.category=Verschiebe Kategorie "{0}" nach
cms.ui.category.move=Kategorie verschieben cms.ui.category.move=Kategorie verschieben
cms.ui.category.cantmoved=Diese Kategorie kann nicht verschoben werden cms.ui.category.cantmoved=Diese Kategorie kann nicht verschoben werden
cms.ui.authoring.error_conflicts_with_this_url=Es gibt Konflikte mit dieser URL. Insbesondere gibt es mindestens ein Dokument in der gleichen Kategorie wie dieser mit dem Namen (URL) cms.ui.authoring.error_conflicts_with_this_url=Es gibt Konflikte mit dieser URL. Insbesondere gibt es mindestens ein Dokument in der gleichen Kategorie wie dieser mit dem Namen (URL)
cms.ui.search.help=Geben sie mindestens drei Buchstaben ein, um nach Content Items zu suchen. Sie k\u00f6nnen das Ergebnis mit weiteren Parametern einschr\u00e4nken.
cms.ui.search.no_results=Es wurden keine Content Items gefunden, die Ihren Suchparametern entsprechen

View File

@ -116,3 +116,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of
cms.ui.search.help=
cms.ui.search.no_results=

View File

@ -590,3 +590,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is atleast one item in the same category as this item with the name (url) of cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is atleast one item in the same category as this item with the name (url) of
cms.ui.search.help=
cms.ui.search.no_results=

View File

@ -22,6 +22,7 @@ import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Page; import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.persistence.OID; import com.arsdigita.persistence.OID;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
@ -105,6 +106,8 @@ public class ItemSearchPopup extends ItemSearch {
public PopupResultsPane(QueryGenerator generator) { public PopupResultsPane(QueryGenerator generator) {
super(generator); super(generator);
setRelativeURLs(true); setRelativeURLs(true);
setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
} }
@Override @Override

View File

@ -29,8 +29,10 @@ import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.ui.search.ItemQueryComponent; import com.arsdigita.cms.ui.search.ItemQueryComponent;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.search.ui.ResultsPane; import com.arsdigita.search.ui.ResultsPane;
import com.arsdigita.search.ui.QueryGenerator; import com.arsdigita.search.ui.QueryGenerator;
@ -139,6 +141,8 @@ public class ItemSearchSection extends FormSection
protected Component createResultsPane(QueryGenerator generator) { protected Component createResultsPane(QueryGenerator generator) {
ResultsPane pane = new ResultsPane(generator); ResultsPane pane = new ResultsPane(generator);
pane.setRelativeURLs(true); pane.setRelativeURLs(true);
pane.setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
pane.setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
return pane; return pane;
} }

View File

@ -27,6 +27,7 @@ import com.arsdigita.toolbox.ui.OIDParameter;
import com.arsdigita.persistence.OID; import com.arsdigita.persistence.OID;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
@ -154,6 +155,8 @@ public class ItemSearchSectionInline extends ItemSearchSection {
public InlineResultsPane(QueryGenerator query) { public InlineResultsPane(QueryGenerator query) {
super(query); super(query);
setRelativeURLs(true); setRelativeURLs(true);
setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
} }
@Override @Override

View File

@ -51,16 +51,16 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
/** /**
* A form for editing subclasses of ContentItem. This is just a convenience * A form for editing subclasses of ContentItem. This is just a convenience class.
* class.
* *
* @author Stanislav Freidin (stas@arsdigita.com) * @author Stanislav Freidin (stas@arsdigita.com)
* @version $Revision: #13 $ $DateTime: 2004/08/17 23:15:09 $ * @version $Revision: #13 $ $DateTime: 2004/08/17 23:15:09 $
**/ *
*/
public abstract class BasicItemForm extends FormSection public abstract class BasicItemForm extends FormSection
implements FormInitListener, implements FormInitListener,
FormProcessListener, FormProcessListener,
FormValidationListener { FormValidationListener {
private static final Logger s_log = Logger.getLogger(BasicItemForm.class); private static final Logger s_log = Logger.getLogger(BasicItemForm.class);
private final ItemSelectionModel m_itemModel; private final ItemSelectionModel m_itemModel;
@ -78,9 +78,9 @@ public abstract class BasicItemForm extends FormSection
* *
* *
* *
* @param formName the name of this form * @param formName the name of this form
* @param itemModel The {@link ItemSelectionModel} which will * @param itemModel The {@link ItemSelectionModel} which will be responsible for loading the
* be responsible for loading the current item * current item
*/ */
public BasicItemForm(String formName, ItemSelectionModel itemModel) { public BasicItemForm(String formName, ItemSelectionModel itemModel) {
super(new ColumnPanel(2)); super(new ColumnPanel(2));
@ -110,13 +110,12 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Construct a new BasicItemForm with a specified number of ColumnPanels * Construct a new BasicItemForm with a specified number of ColumnPanels and without any content
* and without any content
* *
* @param formName the name of this form * @param formName the name of this form
* @param columnPanel the columnpanel of the form * @param columnPanel the columnpanel of the form
* @param itemModel The {@link ItemSelectionModel} which will * @param itemModel The {@link ItemSelectionModel} which will be responsible for loading the
* be responsible for loading the current item * current item
*/ */
public BasicItemForm(String formName, public BasicItemForm(String formName,
ColumnPanel columnPanel, ColumnPanel columnPanel,
@ -124,7 +123,7 @@ public abstract class BasicItemForm extends FormSection
super(columnPanel); super(columnPanel);
m_widgetSection = new FormSection(new ColumnPanel(columnPanel.getNumCols(), m_widgetSection = new FormSection(new ColumnPanel(columnPanel.getNumCols(),
true)); true));
super.add(m_widgetSection, ColumnPanel.INSERT); super.add(m_widgetSection, ColumnPanel.INSERT);
m_itemModel = itemModel; m_itemModel = itemModel;
} }
@ -137,7 +136,6 @@ public abstract class BasicItemForm extends FormSection
super.add(m_saveCancelSection, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT); super.add(m_saveCancelSection, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
} }
/** /**
* Currently, to insert javascript code the Label Widget is "abused". * Currently, to insert javascript code the Label Widget is "abused".
*/ */
@ -148,17 +146,16 @@ public abstract class BasicItemForm extends FormSection
/** /**
* Add basic widgets to the form. * Add basic widgets to the form.
* *
* Widgets added are 'title' and 'name (url)' which are part of any content * Widgets added are 'title' and 'name (url)' which are part of any content item. Child classes
* item. * will override this method to perform all their widget-adding needs but may use super() to add
* Child classes will override this method to perform all their widget-adding * the basic widgets.
* needs but may use super() to add the basic widgets.
*/ */
protected void addWidgets() { protected void addWidgets() {
//add(new FormErrorDisplay(this), ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT); //add(new FormErrorDisplay(this), ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
//add(new Label("id")); //add(new Label("id"));
final Hidden id = new Hidden(CONTENT_ITEM_ID); final Hidden id = new Hidden(CONTENT_ITEM_ID);
//final TextField id = new TextField(CONTENT_ITEM_ID); //final TextField id = new TextField(CONTENT_ITEM_ID);
add(id); add(id);
// JavaScript auto-name generation is off by default. // JavaScript auto-name generation is off by default.
@ -172,7 +169,6 @@ public abstract class BasicItemForm extends FormSection
// created you don't want to subsequently change it since // created you don't want to subsequently change it since
// it breaks URLs & potentially overwrites the user's // it breaks URLs & potentially overwrites the user's
// customizations. // customizations.
// For some content types it is maybe useful to change the label of the // For some content types it is maybe useful to change the label of the
// title field to something different than 'title'. // title field to something different than 'title'.
// This can nowbe done by overwriting the getTitleLabel() method. // This can nowbe done by overwriting the getTitleLabel() method.
@ -184,8 +180,8 @@ public abstract class BasicItemForm extends FormSection
+ " defaulting = true; this.form." + NAME + " defaulting = true; this.form." + NAME
+ ".value = urlize(this.value); }"); + ".value = urlize(this.value); }");
titleWidget.setOnKeyUp( titleWidget.setOnKeyUp(
"if (defaulting) { this.form." + NAME "if (defaulting) { this.form." + NAME
+ ".value = urlize(this.value) }"); + ".value = urlize(this.value) }");
titleWidget.setLabel(getTitleLabel()); titleWidget.setLabel(getTitleLabel());
titleWidget.setHint(getTitleHint()); titleWidget.setHint(getTitleHint());
add(titleWidget); add(titleWidget);
@ -200,9 +196,9 @@ public abstract class BasicItemForm extends FormSection
nameWidget.setMaxLength(190); nameWidget.setMaxLength(190);
nameWidget.setOnFocus("defaulting = false"); nameWidget.setOnFocus("defaulting = false");
nameWidget.setOnBlur( nameWidget.setOnBlur(
"if (this.value == '') " "if (this.value == '') "
+ "{ defaulting = true; this.value = urlize(this.form." + TITLE + "{ defaulting = true; this.value = urlize(this.form." + TITLE
+ ".value) } " + " else { this.value = urlize(this.value); }"); + ".value) } " + " else { this.value = urlize(this.value); }");
nameWidget.addValidationListener(new NotNullValidationListener()); nameWidget.addValidationListener(new NotNullValidationListener());
nameWidget.setHint(getNameHint()); nameWidget.setHint(getNameHint());
add(nameWidget); add(nameWidget);
@ -230,25 +226,28 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Perform form initialization. Children should override this * Perform form initialization. Children should override this this method to pre-fill the
* this method to pre-fill the widgets with data, instantiate * widgets with data, instantiate the content item, etc.
* the content item, etc. *
* @param e * @param e
*
* @throws FormProcessException * @throws FormProcessException
*/ */
public abstract void init(FormSectionEvent e) throws FormProcessException; public abstract void init(FormSectionEvent e) throws FormProcessException;
/** /**
* Process the form. Children should override this method to save * Process the form. Children should override this method to save the user's changes to the
* the user's changes to the database. * database.
*
* @param e * @param e
*
* @throws FormProcessException * @throws FormProcessException
*/ */
public abstract void process(FormSectionEvent e) throws FormProcessException; public abstract void process(FormSectionEvent e) throws FormProcessException;
/** /**
* Validate the form. Children should override this method to provide * Validate the form. Children should override this method to provide custom form validation.
* custom form validation. *
* @param e * @param e
*/ */
public void validate(FormSectionEvent e) throws FormProcessException { public void validate(FormSectionEvent e) throws FormProcessException {
@ -256,17 +255,17 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Ensure that the name of an item is unique within a folder. A "New * Ensure that the name of an item is unique within a folder. A "New item" form should call this
* item" form should call this method in the validation listener. * method in the validation listener.
* *
* @param parent the folder in which to check * @param parent the folder in which to check
* @param event the {@link FormSectionEvent} which was passed to the * @param event the {@link FormSectionEvent} which was passed to the validation listener
* validation listener *
* @throws FormProcessException if the folder already contains an item * @throws FormProcessException if the folder already contains an item with the name the user
* with the name the user provided on the input form. * provided on the input form.
*/ */
public void validateNameUniqueness(Folder parent, FormSectionEvent event) public void validateNameUniqueness(Folder parent, FormSectionEvent event)
throws FormProcessException { throws FormProcessException {
FormData data = event.getFormData(); FormData data = event.getFormData();
String newName = (String) data.get(NAME); String newName = (String) data.get(NAME);
@ -279,11 +278,12 @@ public abstract class BasicItemForm extends FormSection
* @param parent * @param parent
* @param event * @param event
* @param newName * @param newName
*
* @throws FormProcessException * @throws FormProcessException
*/ */
public void validateNameUniqueness(Folder parent, FormSectionEvent event, public void validateNameUniqueness(Folder parent, FormSectionEvent event,
String newName) String newName)
throws FormProcessException { throws FormProcessException {
if (newName != null) { if (newName != null) {
final String query = "com.arsdigita.cms.validateUniqueItemName"; final String query = "com.arsdigita.cms.validateUniqueItemName";
DataQuery dq = SessionManager.getSession().retrieveQuery(query); DataQuery dq = SessionManager.getSession().retrieveQuery(query);
@ -300,20 +300,24 @@ public abstract class BasicItemForm extends FormSection
ContentItem item = null; ContentItem item = null;
if (getItemSelectionModel() != null) { if (getItemSelectionModel() != null) {
item = (ContentItem) getItemSelectionModel(). item = (ContentItem) getItemSelectionModel().
getSelectedObject(event.getPageState()); getSelectedObject(event.getPageState());
} }
if (item == null) { if (item == null) {
// this means it is a creation form // this means it is a creation form
// throw new FormProcessException(
// "An item with this name already exists");
throw new FormProcessException( throw new FormProcessException(
"An item with this name already exists"); "cms.ui.authoring.an_item_with_this_name_already_exists");
} }
Collection list = getAllVersionIDs(item); Collection list = getAllVersionIDs(item);
while (dq.next()) { while (dq.next()) {
itemID = (BigDecimal) dq.get("itemID"); itemID = (BigDecimal) dq.get("itemID");
if (!list.contains(itemID)) { if (!list.contains(itemID)) {
dq.close(); dq.close();
// throw new FormProcessException(
// "An item with this name already exists");
throw new FormProcessException( throw new FormProcessException(
"An item with this name already exists"); "cms.ui.authoring.an_item_with_this_name_already_exists");
} }
} }
} }
@ -321,19 +325,18 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Ensure that the name of an item is unique within a category. This * Ensure that the name of an item is unique within a category. This should only be called from
* should only be called from the validation listener of an "edit" form. * the validation listener of an "edit" form.
* *
* @param event the {@link FormSectionEvent} which was passed to the * @param event the {@link FormSectionEvent} which was passed to the validation listener
* validation listener * @param id The id of the item that is being checked. This must no be null.
* @param id The id of the item that is being checked. This must no *
* be null. * @throws FormProcessException if the folder already contains an item with the name the user
* @throws FormProcessException if the folder already contains an item * provided on the input form.
* with the name the user provided on the input form.
*/ */
public void validateNameUniquenessWithinCategory(FormSectionEvent event, public void validateNameUniquenessWithinCategory(FormSectionEvent event,
BigDecimal id) BigDecimal id)
throws FormProcessException { throws FormProcessException {
if (id == null) { if (id == null) {
s_log.warn("Trying to validation the name uniqueness without " s_log.warn("Trying to validation the name uniqueness without "
+ " a valid item is invalid. This method should only " + " a valid item is invalid. This method should only "
@ -349,9 +352,8 @@ public abstract class BasicItemForm extends FormSection
if (url == null) { if (url == null) {
return; return;
} }
DataQuery query = DataQuery query = SessionManager.getSession().retrieveQuery(
SessionManager.getSession().retrieveQuery( "com.arsdigita.categorization.getAllItemURLsForCategoryFromItem");
"com.arsdigita.categorization.getAllItemURLsForCategoryFromItem");
query.setParameter("itemID", id); query.setParameter("itemID", id);
query.addEqualsFilter("lower(url)", url.toLowerCase()); query.addEqualsFilter("lower(url)", url.toLowerCase());
if (query.size() > 0) { if (query.size() > 0) {
@ -359,9 +361,8 @@ public abstract class BasicItemForm extends FormSection
// pending or live version of the same item // pending or live version of the same item
BigDecimal itemID = null; BigDecimal itemID = null;
ContentItem item = ContentItem item = (ContentItem) getItemSelectionModel().getSelectedObject(event.
(ContentItem) getItemSelectionModel().getSelectedObject(event. getPageState());
getPageState());
Collection list = getAllVersionIDs(item); Collection list = getAllVersionIDs(item);
try { try {
while (query.next()) { while (query.next()) {
@ -369,7 +370,7 @@ public abstract class BasicItemForm extends FormSection
if (!list.contains(itemID)) { if (!list.contains(itemID)) {
StringBuffer buffer = new StringBuffer((String) GlobalizationUtil StringBuffer buffer = new StringBuffer((String) GlobalizationUtil
.globalize("cms.ui.authoring.error_conflicts_with_this_url") .globalize("cms.ui.authoring.error_conflicts_with_this_url")
.localize() ); .localize());
buffer.append(url); buffer.append(url);
throw new FormProcessException(buffer.toString()); throw new FormProcessException(buffer.toString());
} }
@ -402,34 +403,33 @@ public abstract class BasicItemForm extends FormSection
* Adds a component to this container. * Adds a component to this container.
* *
* @param pc the component to add to this BasicPageForm * @param pc the component to add to this BasicPageForm
* */ *
*/
@Override @Override
public void add(Component pc) { public void add(Component pc) {
m_widgetSection.add(pc); m_widgetSection.add(pc);
} }
/** /**
* Adds a component with the specified layout constraints to this * Adds a component with the specified layout constraints to this container. Layout constraints
* container. Layout constraints are defined in each layout container as * are defined in each layout container as static ints. Use a bitwise OR to specify multiple
* static ints. Use a bitwise OR to specify multiple constraints. * constraints.
* *
* @param pc the component to add to this container * @param pc the component to add to this container
* *
* @param constraints layout constraints (a * @param constraints layout constraints (a bitwise OR of static ints in the particular layout)
* bitwise OR of static ints in the particular layout) *
* */ */
@Override @Override
public void add(Component pc, int constraints) { public void add(Component pc, int constraints) {
m_widgetSection.add(pc, constraints); m_widgetSection.add(pc, constraints);
} }
/** /**
* jensp, 2011-01-28 * jensp, 2011-01-28 This method can be overridden to change the label of the title field. To
* This method can be overridden to change the label of the title field. * change to label of the title field can be useful for some content types. For example, for an
* To change to label of the title field can be useful for some * organization the label "Title" for the field is may confusing for the normal user. For such a
* content types. For example, for an organization the label "Title" for * content type, the label would be changed to something like "Name of the organization".
* the field is may confusing for the normal user. For such a content type,
* the label would be changed to something like "Name of the organization".
* *
* @return (Content for the) Label for the title field as string * @return (Content for the) Label for the title field as string
*/ */
@ -438,8 +438,8 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Provides the text for the user hint providing some detailed information * Provides the text for the user hint providing some detailed information how to use this
* how to use this widget. * widget.
* *
* This method can be overwritten to adjust the text for some content types. * This method can be overwritten to adjust the text for some content types.
* {@link #getTitleLabel()} * {@link #getTitleLabel()}
@ -451,9 +451,8 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* jensp, 2011-01-28 * jensp, 2011-01-28 This method does the same as {@link #getTitleLabel() } for the label of the
* This method does the same as {@link #getTitleLabel() } for the label of * name (URL) field.
* the name (URL) field.
* *
* @return (Content for the) Label for the name field as string * @return (Content for the) Label for the name field as string
*/ */
@ -462,8 +461,8 @@ public abstract class BasicItemForm extends FormSection
} }
/** /**
* Provides the text for the unser hint providing some detailed information * Provides the text for the unser hint providing some detailed information how to use this
* how to use this widget. * widget.
* *
* This method can be overwritten to adjust the text for some content types. * This method can be overwritten to adjust the text for some content types.
* {@link #getNameLabel()} * {@link #getNameLabel()}
@ -473,4 +472,5 @@ public abstract class BasicItemForm extends FormSection
protected GlobalizedMessage getNameHint() { protected GlobalizedMessage getNameHint() {
return GlobalizationUtil.globalize("cms.contenttypes.ui.name_hint"); return GlobalizationUtil.globalize("cms.contenttypes.ui.name_hint");
} }
} }

View File

@ -28,13 +28,13 @@ import com.arsdigita.globalization.GlobalizedMessage;
import java.util.Iterator; import java.util.Iterator;
/** /**
* Displays validation errors for the page. These might have occured due to validation * Displays validation errors for the page. These might have occured due to validation listeners on
* listeners on some state parameters within the page. * some state parameters within the page.
* *
* @author Stanislav Freidin * @author Stanislav Freidin
* @version $Id: PageErrorDisplay.java 287 2005-02-22 00:29:02Z sskracic $ * @version $Id: PageErrorDisplay.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public class PageErrorDisplay extends List { public class PageErrorDisplay extends List {
private static final String COLOR = "color"; private static final String COLOR = "color";
@ -46,8 +46,8 @@ public class PageErrorDisplay extends List {
} }
/** /**
* Constructs a new <code>PageErrorDisplay</code> from the errors * Constructs a new <code>PageErrorDisplay</code> from the errors supplied by a list model
* supplied by a list model builder. * builder.
* *
* @param builder the {@link ListModelBuilder} that will supply the errors * @param builder the {@link ListModelBuilder} that will supply the errors
* *
@ -70,6 +70,7 @@ public class PageErrorDisplay extends List {
/** /**
* Gets the HTML color of the error messages. * Gets the HTML color of the error messages.
*
* @return the HTML color of the error messages. * @return the HTML color of the error messages.
*/ */
public String getTextColor() { public String getTextColor() {
@ -80,23 +81,24 @@ public class PageErrorDisplay extends List {
* Determines if there are errors to display. * Determines if there are errors to display.
* *
* @param state the current page state * @param state the current page state
* @return <code>true</code> if there are any errors to display; *
* <code>false</code> otherwise. * @return <code>true</code> if there are any errors to display; <code>false</code> otherwise.
*/ */
protected boolean hasErrors(PageState state) { protected boolean hasErrors(PageState state) {
return(state.getErrors().hasNext()); return (state.getErrors().hasNext());
} }
/** /**
* Generates the XML for this component. If the state has no errors * Generates the XML for this component. If the state has no errors in it, does not generate any
* in it, does not generate any XML. * XML.
* *
* @param state the current page state * @param state the current page state
* @param parent the parent XML element * @param parent the parent XML element
*/ */
public void generateXML(PageState state, Element parent) { public void generateXML(PageState state, Element parent) {
if(hasErrors(state)) if (hasErrors(state)) {
super.generateXML(state, parent); super.generateXML(state, parent);
}
} }
// A private class which builds a ListModel based on form errors // A private class which builds a ListModel based on form errors
@ -110,6 +112,7 @@ public class PageErrorDisplay extends List {
public ListModel makeModel(List l, PageState state) { public ListModel makeModel(List l, PageState state) {
return new StringIteratorModel(state.getErrors()); return new StringIteratorModel(state.getErrors());
} }
} }
// A ListModel which generates items based on an Iterator // A ListModel which generates items based on an Iterator
@ -126,22 +129,22 @@ public class PageErrorDisplay extends List {
} }
public boolean next() { public boolean next() {
if(!m_iter.hasNext()) { if (!m_iter.hasNext()) {
m_i = 0; m_i = 0;
return false; return false;
} }
m_error = (GlobalizedMessage)m_iter.next(); m_error = (GlobalizedMessage) m_iter.next();
++m_i; ++m_i;
return true; return true;
} }
private void checkState() { private void checkState() {
if(m_i == 0) { if (m_i == 0) {
throw new IllegalStateException ( throw new IllegalStateException(
"next() has not been called succesfully" "next() has not been called succesfully"
); );
} }
} }
@ -154,14 +157,17 @@ public class PageErrorDisplay extends List {
checkState(); checkState();
return Integer.toString(m_i); return Integer.toString(m_i);
} }
} }
// A ListCellRenderer that renders labels // A ListCellRenderer that renders labels
private static class LabelCellRenderer implements ListCellRenderer { private static class LabelCellRenderer implements ListCellRenderer {
public Component getComponent(List list, PageState state, Object value, public Component getComponent(List list, PageState state, Object value,
String key, int index, boolean isSelected) { String key, int index, boolean isSelected) {
return new Label((GlobalizedMessage)value); return new Label((GlobalizedMessage) value);
} }
} }
} }

View File

@ -21,7 +21,9 @@ package com.arsdigita.search.ui;
import com.arsdigita.bebop.SimpleComponent; import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.IntegerParameter; import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.bebop.util.GlobalizationUtil;
import com.arsdigita.globalization.Globalization; import com.arsdigita.globalization.Globalization;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Party; import com.arsdigita.kernel.Party;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
@ -44,265 +46,287 @@ import org.apache.log4j.Logger;
public class ResultsPane extends SimpleComponent { public class ResultsPane extends SimpleComponent {
private static final Logger s_log = Logger.getLogger(ResultsPane.class); private static final Logger s_log = Logger.getLogger(ResultsPane.class);
public static final int PAGE_SIZE = 10; public static final int PAGE_SIZE = 10;
private int m_pageSize = PAGE_SIZE; private int m_pageSize = PAGE_SIZE;
private String m_engine; private String m_engine;
private QueryGenerator m_query; private QueryGenerator m_query;
private IntegerParameter m_pageNumber; private IntegerParameter m_pageNumber;
private boolean m_relative; private boolean m_relative;
//jensp 2014-03-04 Allow using classes to set a suitable info messages.
private GlobalizedMessage searchHelpMsg;
private GlobalizedMessage noResultsMsg;
public ResultsPane(QueryGenerator query) { public ResultsPane(QueryGenerator query) {
this(query, null); this(query, null);
} }
/** /**
* Determines whether the links to the search results will be relative or * Determines whether the links to the search results will be relative or absolute. The default
* absolute. The default is absolute. * is absolute.
*/ */
public void setRelativeURLs(boolean relative) { public void setRelativeURLs(boolean relative) {
m_relative = relative; m_relative = relative;
} }
public ResultsPane(QueryGenerator query, public ResultsPane(QueryGenerator query,
String engine) { String engine) {
m_query = query; m_query = query;
m_engine = engine; m_engine = engine;
m_pageNumber = new IntegerParameter("page"); m_pageNumber = new IntegerParameter("page");
m_relative = false; m_relative = false;
} }
@Override public void setSearchHelpMsg(final GlobalizedMessage msg) {
public void generateXML(PageState state, Element parent) { searchHelpMsg = msg;
if (!m_query.hasQuery(state)) { }
if (s_log.isDebugEnabled()) {
s_log.debug("No query available, skipping XMl generation");
}
Element content = Search.newElement("results");
Element info = content.newChildElement("info");
// info.setText(GlobalizationUtil.globalize("cms.ui.search_help").localize().toString());
info.setText("To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.");
parent.addContent(content);
return;
}
QuerySpecification spec = m_query.getQuerySpecification(state); public void setNoResultsMsg(final GlobalizedMessage msg) {
ResultSet resultSet = null; noResultsMsg = msg;
try { }
resultSet = m_engine == null
? Search.process(spec)
: Search.process(spec, Search.DEFAULT_RESULT_CACHE,
m_engine);
if (s_log.isDebugEnabled()) { @Override
s_log.debug("Got result set " + resultSet.getClass() public void generateXML(PageState state, Element parent) {
+ " count: " + resultSet.getCount()); if (!m_query.hasQuery(state)) {
} if (s_log.isDebugEnabled()) {
s_log.debug("No query available, skipping XMl generation");
}
Element content = Search.newElement("results");
Element info = content.newChildElement("info");
if (searchHelpMsg == null) {
info.setText(
"To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.");
} else {
//info.setText(GlobalizationUtil.globalize("cms.ui.search_help").localize().toString());
info.setText(searchHelpMsg.localize().toString());
}
if (resultSet.getCount() > 0) { parent.addContent(content);
return;
}
Integer page = (Integer) m_pageNumber.transformValue(state. QuerySpecification spec = m_query.getQuerySpecification(state);
getRequest()); ResultSet resultSet = null;
int pageNumber = (page == null ? 1 : page.intValue()); try {
long objectCount = resultSet.getCount(); resultSet = m_engine == null
int pageCount = (int) Math.ceil((double) objectCount ? Search.process(spec)
/ (double) m_pageSize); : Search.process(spec, Search.DEFAULT_RESULT_CACHE,
m_engine);
if (pageNumber < 1) { if (s_log.isDebugEnabled()) {
pageNumber = 1; s_log.debug("Got result set " + resultSet.getClass()
} + " count: " + resultSet.getCount());
}
if (pageNumber > pageCount) { if (resultSet.getCount() > 0) {
pageNumber = (pageCount == 0 ? 1 : pageCount);
}
long begin = ((pageNumber - 1) * m_pageSize); Integer page = (Integer) m_pageNumber.transformValue(state.
int count = (int) Math.min(m_pageSize, (objectCount - begin)); getRequest());
long end = begin + count; int pageNumber = (page == null ? 1 : page.intValue());
long objectCount = resultSet.getCount();
int pageCount = (int) Math.ceil((double) objectCount
/ (double) m_pageSize);
Iterator results = resultSet.getDocuments(begin, count); if (pageNumber < 1) {
pageNumber = 1;
}
Element content = Search.newElement("results"); if (pageNumber > pageCount) {
exportAttributes(content); pageNumber = (pageCount == 0 ? 1 : pageCount);
}
if (s_log.isDebugEnabled()) { long begin = ((pageNumber - 1) * m_pageSize);
s_log.debug("Paginator stats\n page number:" + pageNumber int count = (int) Math.min(m_pageSize, (objectCount - begin));
+ "\n page count: " + pageCount long end = begin + count;
+ "\n page size: "
+ m_pageSize + "\n start " + begin + "\n end: "
+ end + "\n count: " + objectCount);
}
content.addContent(generatePaginatorXML(state, Iterator results = resultSet.getDocuments(begin, count);
m_pageNumber.getName(),
pageNumber, pageCount,
m_pageSize, begin, end,
objectCount));
content.addContent(generateDocumentsXML(state, results));
parent.addContent(content); Element content = Search.newElement("results");
} else { exportAttributes(content);
// No search result, so we don't need a paginator, but we want
// to inform the user, that there are no results for this search if (s_log.isDebugEnabled()) {
Element content = Search.newElement("results"); s_log.debug("Paginator stats\n page number:" + pageNumber
Element info = content.newChildElement("info"); + "\n page count: " + pageCount
+ "\n page size: "
+ m_pageSize + "\n start " + begin + "\n end: "
+ end + "\n count: " + objectCount);
}
content.addContent(generatePaginatorXML(state,
m_pageNumber.getName(),
pageNumber, pageCount,
m_pageSize, begin, end,
objectCount));
content.addContent(generateDocumentsXML(state, results));
parent.addContent(content);
} else {
// No search result, so we don't need a paginator, but we want
// to inform the user, that there are no results for this search
Element content = Search.newElement("results");
Element info = content.newChildElement("info");
// info.setText(GlobalizationUtil.globalize("cms.ui.search_no_results").localize().toString()); // info.setText(GlobalizationUtil.globalize("cms.ui.search_no_results").localize().toString());
info.setText("Sorry. Your search returned 0 results."); if (noResultsMsg == null) {
parent.addContent(content); info.setText("Sorry. Your search returned 0 results.");
} } else {
info.setText(noResultsMsg.localize().toString());
}
parent.addContent(content);
}
} finally { } finally {
if (resultSet != null) { if (resultSet != null) {
try { try {
resultSet.close(); resultSet.close();
} catch (Exception e) { } catch (Exception e) {
/* /*
* If there is a problem closing the result set this probably means * If there is a problem closing the result set this probably means
* it has been closed elsewhere and is probably not fatal. We write * it has been closed elsewhere and is probably not fatal. We write
* a line to the error log but otherwise ignore the exception allowing * a line to the error log but otherwise ignore the exception allowing
* the code to continue normally. Any issues willemerge in the log. * the code to continue normally. Any issues willemerge in the log.
*/ */
s_log.error("Error closing resultset: " + e.getMessage()); s_log.error("Error closing resultset: " + e.getMessage());
} }
} }
} }
} }
protected Element generatePaginatorXML(PageState state, protected Element generatePaginatorXML(PageState state,
String pageParam, String pageParam,
int pageNumber, int pageNumber,
int pageCount, int pageCount,
int pageSize, int pageSize,
long begin, long begin,
long end, long end,
long objectCount) { long objectCount) {
Element paginator = Search.newElement("paginator"); Element paginator = Search.newElement("paginator");
URL url = Web.getContext().getRequestURL(); URL url = Web.getContext().getRequestURL();
ParameterMap map = new ParameterMap(); ParameterMap map = new ParameterMap();
Iterator current = url.getParameterMap().keySet().iterator(); Iterator current = url.getParameterMap().keySet().iterator();
while (current.hasNext()) { while (current.hasNext()) {
String key = (String) current.next(); String key = (String) current.next();
if (key.equals(pageParam)) { if (key.equals(pageParam)) {
continue; continue;
} }
//map.setParameterValues(key, url.getParameterValues(key)); //map.setParameterValues(key, url.getParameterValues(key));
map.setParameterValues(key, map.setParameterValues(key,
decodeParameters(url.getParameterValues(key), decodeParameters(url.getParameterValues(key),
state)); state));
} }
paginator.addAttribute("pageParam", m_pageNumber.getName()); paginator.addAttribute("pageParam", m_pageNumber.getName());
paginator.addAttribute("baseURL", URL.there(url.getPathInfo(), map). paginator.addAttribute("baseURL", URL.there(url.getPathInfo(), map).
toString()); toString());
paginator.addAttribute("pageNumber", XML.format(new Integer(pageNumber))); paginator.addAttribute("pageNumber", XML.format(new Integer(pageNumber)));
paginator.addAttribute("pageCount", XML.format(new Integer(pageCount))); paginator.addAttribute("pageCount", XML.format(new Integer(pageCount)));
paginator.addAttribute("pageSize", XML.format(new Integer(pageSize))); paginator.addAttribute("pageSize", XML.format(new Integer(pageSize)));
paginator.addAttribute("objectBegin", XML.format(new Long(begin + 1))); paginator.addAttribute("objectBegin", XML.format(new Long(begin + 1)));
paginator.addAttribute("objectEnd", XML.format(new Long(end))); paginator.addAttribute("objectEnd", XML.format(new Long(end)));
paginator.addAttribute("objectCount", XML.format(new Long(objectCount))); paginator.addAttribute("objectCount", XML.format(new Long(objectCount)));
return paginator; return paginator;
} }
private String[] decodeParameters(final String[] parameters, private String[] decodeParameters(final String[] parameters,
final PageState state) { final PageState state) {
final String[] decoded = new String[parameters.length]; final String[] decoded = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) { for (int i = 0; i < parameters.length; i++) {
decoded[i] = decodeParameter(parameters[i], state); decoded[i] = decodeParameter(parameters[i], state);
} }
return decoded; return decoded;
} }
private String decodeParameter(final String parameter, private String decodeParameter(final String parameter,
final PageState state) { final PageState state) {
String re = state.getRequest().getParameter(Globalization.ENCODING_PARAM_NAME); String re = state.getRequest().getParameter(Globalization.ENCODING_PARAM_NAME);
if ((re == null) || (re.isEmpty())) { if ((re == null) || (re.isEmpty())) {
re = Globalization.getDefaultCharset(); re = Globalization.getDefaultCharset();
} }
if ((parameter == null) || (parameter.isEmpty())) { if ((parameter == null) || (parameter.isEmpty())) {
return parameter; return parameter;
} else if (Globalization.getDefaultCharset(state.getRequest()).equals(re)) { } else if (Globalization.getDefaultCharset(state.getRequest()).equals(re)) {
return parameter; return parameter;
} else { } else {
try { try {
return new String(parameter.getBytes(Globalization.getDefaultCharset( return new String(parameter.getBytes(Globalization.getDefaultCharset(
state.getRequest())), re); state.getRequest())), re);
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
s_log.warn("Unsupported encoding.", ex); s_log.warn("Unsupported encoding.", ex);
return parameter; return parameter;
} }
} }
} }
protected Element generateDocumentsXML(PageState state, protected Element generateDocumentsXML(PageState state,
Iterator results) { Iterator results) {
Element documents = Search.newElement("documents"); Element documents = Search.newElement("documents");
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("Outputting documents"); s_log.debug("Outputting documents");
} }
while (results.hasNext()) { while (results.hasNext()) {
Document doc = (Document) results.next(); Document doc = (Document) results.next();
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("One doc " + doc.getOID() + " " + doc.getTitle()); s_log.debug("One doc " + doc.getOID() + " " + doc.getTitle());
} }
documents.addContent(generateDocumentXML(state, doc)); documents.addContent(generateDocumentXML(state, doc));
} }
return documents; return documents;
} }
protected Element generateDocumentXML(PageState state, protected Element generateDocumentXML(PageState state,
Document doc) { Document doc) {
Element entry = Search.newElement("object"); Element entry = Search.newElement("object");
String summary = doc.getSummary(); String summary = doc.getSummary();
java.net.URL url = doc.getURL(); java.net.URL url = doc.getURL();
entry.addAttribute("oid", XML.format(doc.getOID())); entry.addAttribute("oid", XML.format(doc.getOID()));
entry.addAttribute("url", XML.format(m_relative ? url.getPath() + "?" entry.addAttribute("url", XML.format(m_relative ? url.getPath() + "?"
+ url.getQuery() + url.getQuery()
: url.toString())); : url.toString()));
entry.addAttribute("score", XML.format(doc.getScore())); entry.addAttribute("score", XML.format(doc.getScore()));
entry.addAttribute("title", XML.format(doc.getTitle())); entry.addAttribute("title", XML.format(doc.getTitle()));
if (summary != null) { if (summary != null) {
entry.addAttribute("summary", XML.format(summary)); entry.addAttribute("summary", XML.format(summary));
} }
entry.addAttribute("locale", XML.format(doc.getLocale())); entry.addAttribute("locale", XML.format(doc.getLocale()));
Date creationDate = doc.getCreationDate(); Date creationDate = doc.getCreationDate();
if (creationDate != null) { if (creationDate != null) {
entry.addAttribute("creationDate", XML.format( entry.addAttribute("creationDate", XML.format(
creationDate.toString())); creationDate.toString()));
} }
Party creationParty = doc.getCreationParty(); Party creationParty = doc.getCreationParty();
if (creationParty != null) { if (creationParty != null) {
entry.addAttribute("creationParty", entry.addAttribute("creationParty",
XML.format(creationParty.getDisplayName())); XML.format(creationParty.getDisplayName()));
} }
Date lastModifiedDate = doc.getLastModifiedDate(); Date lastModifiedDate = doc.getLastModifiedDate();
if (lastModifiedDate != null) { if (lastModifiedDate != null) {
entry.addAttribute("lastModifiedDate", entry.addAttribute("lastModifiedDate",
XML.format(lastModifiedDate)); XML.format(lastModifiedDate));
} }
Party lastModifiedParty = doc.getLastModifiedParty(); Party lastModifiedParty = doc.getLastModifiedParty();
if (lastModifiedParty != null) { if (lastModifiedParty != null) {
entry.addAttribute("lastModifiedParty", entry.addAttribute("lastModifiedParty",
XML.format(lastModifiedParty.getDisplayName())); XML.format(lastModifiedParty.getDisplayName()));
} }
s_log.debug( s_log.debug(
"about to add the contentSectionName from search index Doc to search result xml"); "about to add the contentSectionName from search index Doc to search result xml");
entry.addAttribute("contentSectionName", XML.format(doc. entry.addAttribute("contentSectionName", XML.format(doc.
getContentSection())); getContentSection()));
return entry;
}
return entry;
}
} }

View File

@ -130,7 +130,9 @@ public class DispatcherServlet extends BaseServlet {
s_log.debug("Successfully dispatched to an application"); s_log.debug("Successfully dispatched to an application");
} else { } else {
s_log.debug("Could not dispatch this request to an " + s_log.debug("Could not dispatch this request to an " +
"application; using the fallback servlet"); "application; sending 404");
sresp.sendError(HttpServletResponse.SC_NOT_FOUND);
/* /*
sreq.setAttribute(FALLING_BACK_ATTRIBUTE, Boolean.TRUE); sreq.setAttribute(FALLING_BACK_ATTRIBUTE, Boolean.TRUE);
@ -143,6 +145,8 @@ public class DispatcherServlet extends BaseServlet {
m_dispatcher.forward(fallbackDispatcher, sreq, sresp); m_dispatcher.forward(fallbackDispatcher, sreq, sresp);
DeveloperSupport.endStage("BaseDispatcher.forward"); DeveloperSupport.endStage("BaseDispatcher.forward");
*/ */
} }
} }

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2002-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.london.search;
import com.arsdigita.globalization.Globalized;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Compilation of methods to simplify the handling of globalizing keys.
* Basically it adds the name of package's resource bundle files to the
* globalize methods and forwards to GlobalizedMessage, shortening the
* method invocation in the various application classes.
*
* @author <a href="mailto:yon@arsdigita.com">yon@arsdigita.com</a>
* @version $Revision$ $Date$
*/
public class SearchGlobalizationUtil implements Globalized {
/** Name of Java resource files to handle CMS's globalisation. */
private static final String BUNDLE_NAME = "com.arsdigita.london.search.SearchResources";
/**
* Returns a globalized message using the package specific bundle,
* provided by BUNDLE_NAME.
*/
public static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, BUNDLE_NAME);
}
/**
* Returns a globalized message object, using the package specific bundle,
* as specified by BUNDLE_NAME. Also takes in an Object[] of arguments to
* interpolate into the retrieved message using the MessageFormat class.
*/
public static GlobalizedMessage globalize(String key, Object[] args) {
return new GlobalizedMessage(key, BUNDLE_NAME, args);
}
/**
* Returns the name of the package specific resource bundle.
*
* Used e.g. by com.arsdigita.cms.ui.item.ItemLanguageTable to get the
* bundle tp pass to DataTable.
*
* @return Name of resource bundle as String
*/
public static String getBundleName() {
return BUNDLE_NAME;
}
}

View File

@ -0,0 +1,7 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
search.ui.submit_button=Find
search.ui.help=Please enter at least three letters for a search. You may narrow the result by adding further parameters.
search.ui.no_results=No results found.

View File

@ -0,0 +1,7 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
search.ui.submit_button=Finden
search.ui.help=Bitte geben Sie miindestens drei Buchstaben f\u00fcr die Suche ein. Sie k\u00f6nnen das Ergebnis mit weiteren Suchparametern weiter einschr\u00e4nken.
search.ui.no_results=Keine Ergebnisse gefunden.

View File

@ -26,6 +26,7 @@ import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.cms.ui.ItemSearch; import com.arsdigita.cms.ui.ItemSearch;
import com.arsdigita.london.search.SearchGlobalizationUtil;
import com.arsdigita.search.ui.QueryComponent; import com.arsdigita.search.ui.QueryComponent;
import com.arsdigita.search.ui.ResultsPane; import com.arsdigita.search.ui.ResultsPane;
@ -49,9 +50,11 @@ public class SearchComponent extends SimpleContainer {
m_form = new Form("search", new SimpleContainer()); m_form = new Form("search", new SimpleContainer());
m_form.setMethod(Form.GET); m_form.setMethod(Form.GET);
m_form.add(m_query); m_form.add(m_query);
m_form.add(new Submit("search", "Search")); m_form.add(new Submit("search", SearchGlobalizationUtil.globalize("search.ui.submit_button")));
m_results = new ResultsPane(query, engine); m_results = new ResultsPane(query, engine);
m_results.setSearchHelpMsg(SearchGlobalizationUtil.globalize("search.ui.help"));
m_results.setNoResultsMsg(SearchGlobalizationUtil.globalize("search.ui.no_results"));
add(m_form); add(m_form);