Dies ist die erste Version der lokalisierten Kategorien.
Folgendes funktioniert: - Anlegen und Löschen von Sprachversionen per Adminoberfläche - Config-Parameter für Fallback-Modus, unterstützte Sprachen und Standard-Sprache - Lokalisierte URLs in navigation - Dekativieren von Sprachversionen Folgendes funktioniert noch nicht: - Bearbeiten von Sprachversionen per Adminoberfläche - evt. ist die Untersützung von lokalisierten URLs noch nicht vollständig d.h. in anderen Anwendungen als navigation Quasimodo git-svn-id: https://svn.libreccm.org/ccm/trunk@41 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
606b7d90d9
commit
42b45983b8
|
|
@ -262,6 +262,7 @@ cms.ui.cannot_assign_groups_to_owner=cannot assign groups to owner
|
|||
cms.ui.categories=Categories
|
||||
cms.ui.category._back= (back)
|
||||
cms.ui.category.add=Add category
|
||||
cms.ui.categoryLocalization.add=Add category localization
|
||||
cms.ui.category.add_index_item=Set index item
|
||||
cms.ui.category.add_use_context=Add Use Context
|
||||
cms.ui.category.assigned_purposes=Assigned Purposes:
|
||||
|
|
@ -280,6 +281,7 @@ cms.ui.category.delete_prompt=Are you sure you want to delete this category?
|
|||
cms.ui.category.descriptionn=Description:\n
|
||||
cms.ui.category.details=Category details
|
||||
cms.ui.category.edit=Edit category
|
||||
cms.ui.categoryLocalization.edit=Edit category
|
||||
cms.ui.category.edit_a_category=Edit a Category
|
||||
cms.ui.category.edit_purposes=Edit purposes
|
||||
cms.ui.category.index_item.select=Select an index item for this category
|
||||
|
|
@ -291,6 +293,16 @@ cms.ui.category.is_not_abstract=Can you place objects in this category?
|
|||
cms.ui.category.item.none=There are no items in this category
|
||||
cms.ui.category.item=Categorized item
|
||||
cms.ui.category.labeln=Label:\n
|
||||
cms.ui.category.localizations=Category Localizations
|
||||
cms.ui.category.localization.add=Add localization
|
||||
cms.ui.category.localization.name=Name
|
||||
cms.ui.category.localization.description=Description
|
||||
cms.ui.category.localization.url=URL
|
||||
cms.ui.category.localization.locale=Language
|
||||
cms.ui.category.localization.action=Action
|
||||
cms.ui.category.localization.confirm_delete=Delete this localization?
|
||||
cms.ui.category.localization.none=This category has no localizations
|
||||
cms.ui.category.localization.error_locale=Please select a locale
|
||||
cms.ui.category.linked.add=Add or remove linked categories
|
||||
cms.ui.category.linked.none=This category has no linked categories
|
||||
cms.ui.category.linked=Linked categories
|
||||
|
|
|
|||
|
|
@ -295,6 +295,16 @@ cms.ui.category.labeln=Label:\n
|
|||
cms.ui.category.linked.add=Verkn\u00FCpfte Kategorien hinzuf\u00FCgen oder entfernen
|
||||
cms.ui.category.linked.none=Diese Kategorie hat keine verkn\u00FCpften Kategorien
|
||||
cms.ui.category.linked=Verkn\u00FCpfte Kategorien
|
||||
cms.ui.category.localizations=Sprachversionen
|
||||
cms.ui.category.localization.add=Sprachversion hinzuf\u00FCgen
|
||||
cms.ui.category.localization.name=Name
|
||||
cms.ui.category.localization.description=Beschreibung
|
||||
cms.ui.category.localization.url=URL
|
||||
cms.ui.category.localization.locale=Sprache
|
||||
cms.ui.category.localization.action=Aktion
|
||||
cms.ui.category.localization.confirm_delete=Soll diese Sprachversion gelöscht werden?
|
||||
cms.ui.category.localization.none=Diese Kategorie hat keine Sprachversionen
|
||||
cms.ui.category.localization.error_locale=Bitte wählen Sie eine Sprache aus
|
||||
cms.ui.category.name_not_unique=Es gibt bereits eine Kategorie mit diesem Namen.
|
||||
cms.ui.category.no_categorized_objects=Es gibt keine kategorisierten Objekte
|
||||
cms.ui.category.no_category_purposes=No Category Purposes
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@ class BaseCategoryForm extends BaseForm {
|
|||
final TextField m_url;
|
||||
final RadioGroup m_isAbstract;
|
||||
final RadioGroup m_isEnabled;
|
||||
private Label m_script = new Label("<script language=\"javascript\" src=\"/javascript/manipulate-input.js\"></script>", false);
|
||||
|
||||
|
||||
private Label m_script = new Label("<script language=\"javascript\" src=\"/javascript/manipulate-input.js\"></script>", false);
|
||||
|
||||
private final static String NAME = "name";
|
||||
private final static String DESCRIPTION = "description";
|
||||
|
|
|
|||
|
|
@ -91,22 +91,28 @@ public final class CategoryAdminPane extends BaseAdminPane {
|
|||
m_contextModel = new UseContextSelectionModel(new StringParameter(CONTEXT_SELECTED));
|
||||
|
||||
|
||||
|
||||
/* Left column */
|
||||
/* Use context section */
|
||||
List list = new List(new CategoryUseContextModelBuilder());
|
||||
list.setSelectionModel(m_contextModel);
|
||||
list.addChangeListener(new ContextSelectionListener());
|
||||
|
||||
/* Category tree section */
|
||||
m_categoryTree = new BaseTree(new CategoryTreeModelBuilder(m_contextModel));
|
||||
m_categoryTree.addChangeListener(new SelectionListener());
|
||||
m_model = m_categoryTree.getSelectionModel();
|
||||
|
||||
|
||||
setSelectionModel(m_model);
|
||||
setSelector(m_categoryTree);
|
||||
|
||||
/* setup use context form */
|
||||
final Section contextSection = new Section();
|
||||
contextSection.setHeading(new Label(gz("cms.ui.category.use_contexts")));
|
||||
ActionGroup contextGroup = new ActionGroup();
|
||||
contextSection.setBody(contextGroup);
|
||||
contextGroup.setSubject(list);
|
||||
|
||||
/* Add use context form to pane */
|
||||
ActionLink addContextAction = new ActionLink(new Label(gz("cms.ui.category.add_use_context")));
|
||||
Form addContextForm = new AddUseContextForm(m_contextModel);
|
||||
getBody().add(addContextForm);
|
||||
|
|
@ -129,6 +135,10 @@ public final class CategoryAdminPane extends BaseAdminPane {
|
|||
m_parent = new ParentRequestLocal();
|
||||
m_category = new SelectionRequestLocal();
|
||||
|
||||
/* Right column */
|
||||
/* Context section aka category details */
|
||||
|
||||
/* Action links */
|
||||
setAdd(gz("cms.ui.category.add"),
|
||||
new CategoryAddForm(m_category, m_model));
|
||||
|
||||
|
|
|
|||
|
|
@ -73,8 +73,17 @@ public final class CategoryCollectionListModel implements ListModel {
|
|||
return m_cat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Namen der Kategorie aus. Angepaßt, damit hier immer
|
||||
* der Wert aus Category gelesen wird und nicht die lokalisierte
|
||||
* Version. Ist hier sinnvoll, da es Teil der Adminoberfläche für
|
||||
* Kategorien ist. Eine lokalisierte Anzeige würde hier nur zu
|
||||
* Verwirrung führen.
|
||||
*
|
||||
* Quasimodo
|
||||
*/
|
||||
public Object getElement() {
|
||||
return getCategory().getName();
|
||||
return getCategory().getName("");
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ final class CategoryEditForm extends BaseCategoryForm {
|
|||
final PageState state = e.getPageState();
|
||||
final Category category = m_category.getCategory(state);
|
||||
|
||||
m_name.setValue(state, category.getName());
|
||||
m_description.setValue(state, category.getDescription());
|
||||
m_url.setValue(state, category.getURL());
|
||||
m_name.setValue(state, category.getName(""));
|
||||
m_description.setValue(state, category.getDescription(""));
|
||||
m_url.setValue(state, category.getURL(""));
|
||||
// this seems anti-intuitive but the question is "can you place
|
||||
// items in this category. If the user says "yes" then the
|
||||
// category is not abstract
|
||||
|
|
@ -73,7 +73,7 @@ final class CategoryEditForm extends BaseCategoryForm {
|
|||
m_isAbstract.setValue(state, "yes");
|
||||
}
|
||||
|
||||
if (category.isEnabled()) {
|
||||
if (category.isEnabled("")) {
|
||||
m_isEnabled.setValue(state, "yes");
|
||||
} else {
|
||||
m_isEnabled.setValue(state, "no");
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.arsdigita.bebop.event.ActionListener;
|
|||
import com.arsdigita.bebop.event.ChangeEvent;
|
||||
import com.arsdigita.bebop.event.ChangeListener;
|
||||
import com.arsdigita.bebop.form.Submit;
|
||||
import com.arsdigita.categorization.CategorizationConfig;
|
||||
import com.arsdigita.categorization.CategorizedCollection;
|
||||
import com.arsdigita.categorization.Category;
|
||||
import com.arsdigita.categorization.CategoryNotFoundException;
|
||||
|
|
@ -54,6 +55,7 @@ import com.arsdigita.persistence.DataObject;
|
|||
import com.arsdigita.persistence.OID;
|
||||
import com.arsdigita.toolbox.ui.ActionGroup;
|
||||
import com.arsdigita.toolbox.ui.PropertyList;
|
||||
import com.arsdigita.toolbox.ui.PropertyList.Property;
|
||||
import com.arsdigita.toolbox.ui.Section;
|
||||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.web.Web;
|
||||
|
|
@ -73,146 +75,172 @@ import org.apache.log4j.Logger;
|
|||
*/
|
||||
class CategoryItemPane extends BaseItemPane {
|
||||
public static final String versionId =
|
||||
"$Id: CategoryItemPane.java 1329 2006-09-27 11:47:05Z sskracic $" +
|
||||
"$Author: sskracic $" +
|
||||
"$DateTime: 2004/08/17 23:15:09 $";
|
||||
|
||||
"$Id: CategoryItemPane.java 1329 2006-09-27 11:47:05Z sskracic $" +
|
||||
"$Author: sskracic $" +
|
||||
"$DateTime: 2004/08/17 23:15:09 $";
|
||||
|
||||
private static final Logger s_log = Logger.getLogger
|
||||
(CategoryItemPane.class);
|
||||
|
||||
(CategoryItemPane.class);
|
||||
|
||||
private final SingleSelectionModel m_model;
|
||||
private final CategoryRequestLocal m_category;
|
||||
|
||||
|
||||
private final SimpleContainer m_detailPane;
|
||||
|
||||
|
||||
public CategoryItemPane(final SingleSelectionModel model,
|
||||
final CategoryRequestLocal category,
|
||||
final ActionLink addLink,
|
||||
final ActionLink editLink,
|
||||
final ActionLink deleteLink) {
|
||||
final CategoryRequestLocal category,
|
||||
final ActionLink addLink,
|
||||
final ActionLink editLink,
|
||||
final ActionLink deleteLink) {
|
||||
m_model = model;
|
||||
m_category = category;
|
||||
|
||||
|
||||
// Details
|
||||
|
||||
|
||||
m_detailPane = new SimpleContainer();
|
||||
add(m_detailPane);
|
||||
setDefault(m_detailPane);
|
||||
|
||||
final ActionLink orderItemsLink =
|
||||
new ActionLink(new Label(gz("cms.ui.category.categorized_objects"))) {
|
||||
public boolean isVisible(PageState state) {
|
||||
// update for live items only
|
||||
if (!super.isVisible(state)) {
|
||||
return false;
|
||||
}
|
||||
CategorizedCollection items = m_category.getCategory
|
||||
(state).getObjects(ContentItem.BASE_DATA_OBJECT_TYPE);
|
||||
items.addEqualsFilter(ContentItem.VERSION,ContentItem.LIVE);
|
||||
boolean canOrder = items.size() > 1;
|
||||
items.close();
|
||||
return canOrder;
|
||||
|
||||
final ActionLink orderItemsLink = new ActionLink(new Label(gz("cms.ui.category.categorized_objects"))) {
|
||||
public boolean isVisible(PageState state) {
|
||||
// update for live items only
|
||||
if (!super.isVisible(state)) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
CategorizedCollection items = m_category.getCategory
|
||||
(state).getObjects(ContentItem.BASE_DATA_OBJECT_TYPE);
|
||||
items.addEqualsFilter(ContentItem.VERSION,ContentItem.LIVE);
|
||||
boolean canOrder = items.size() > 1;
|
||||
items.close();
|
||||
return canOrder;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
final Form orderItemsForm = new OrderItemsForm(m_category);
|
||||
final Form orderItemsForm2 = new OrderItemsForm(m_category);
|
||||
add(orderItemsForm);
|
||||
add(orderItemsForm2);
|
||||
|
||||
|
||||
// Change index item
|
||||
final ActionLink indexLink = new ActionLink(new Label(gz("cms.ui.category.change_index_item")));
|
||||
final Form indexForm = new IndexItemSelectionForm(m_category);
|
||||
add(indexForm);
|
||||
|
||||
|
||||
ViewItemLink viewIndexLink = new ViewItemLink(new Label(gz("cms.ui.category.view_index_item")),"");
|
||||
EditItemLink editIndexLink = new EditItemLink(new Label(gz("cms.ui.category.edit_index_item")),"");
|
||||
|
||||
|
||||
// Summary
|
||||
m_detailPane.add(new SummarySection(editLink, deleteLink, indexLink, viewIndexLink, editIndexLink, orderItemsLink));
|
||||
|
||||
// Quasimodo: BEGIN
|
||||
// Localizations
|
||||
ActionLink addCategoryLocalizationLink = new ActionLink(new Label(gz("cms.ui.category.localization.add"))) {
|
||||
public boolean isVisible(PageState state) {
|
||||
// Only show addLanguage button, if there are langauges to add
|
||||
int countSupportedLanguages = (new CategorizationConfig()).getSupportedLanguages().countTokens();
|
||||
long countLanguages = m_category.getCategory(state).getCategoryLocalizationCollection().size();
|
||||
|
||||
if(countLanguages < countSupportedLanguages) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CategoryLocalizationAddForm addCategoryLocalizationForm = new CategoryLocalizationAddForm(m_category);
|
||||
m_detailPane.add(new CategoryLocalizationSection(addCategoryLocalizationLink));
|
||||
add(addCategoryLocalizationForm);
|
||||
connect(addCategoryLocalizationLink, addCategoryLocalizationForm);
|
||||
connect(addCategoryLocalizationForm);
|
||||
// Quasimodo: END
|
||||
|
||||
// Subcategories
|
||||
m_detailPane.add(new SubcategorySection(addLink));
|
||||
|
||||
|
||||
// Linked categories
|
||||
final ActionLink linkAddLink = new ActionLink
|
||||
(new Label(gz("cms.ui.category.linked.add")));
|
||||
|
||||
(new Label(gz("cms.ui.category.linked.add")));
|
||||
|
||||
final Form linkForm = new LinkForm(m_category);
|
||||
add(linkForm);
|
||||
|
||||
|
||||
linkAddLink.addActionListener(new NavigationListener(linkForm));
|
||||
linkForm.addSubmissionListener(new CancelListener(linkForm));
|
||||
|
||||
|
||||
m_detailPane.add(new LinkedCategorySection(linkAddLink));
|
||||
|
||||
|
||||
// Templates
|
||||
m_detailPane.add(new AdminVisible(new CategoryTemplateSection()));
|
||||
|
||||
|
||||
// Permissions
|
||||
m_detailPane.add(new PermissionsSection());
|
||||
|
||||
|
||||
connect(indexLink, indexForm);
|
||||
connect(indexForm);
|
||||
|
||||
|
||||
connect(orderItemsLink, orderItemsForm);
|
||||
connect(orderItemsForm);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class EditVisible extends VisibilityComponent {
|
||||
EditVisible(final Component child) {
|
||||
super(child, null);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPermission(PageState ps) {
|
||||
return m_category.getCategory(ps).canEdit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class AdminVisible extends VisibilityComponent {
|
||||
AdminVisible(final Component child) {
|
||||
super(child, null);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPermission(PageState ps) {
|
||||
return m_category.getCategory(ps).canAdmin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class SummarySection extends Section {
|
||||
|
||||
|
||||
SummarySection(final ActionLink editLink,
|
||||
final ActionLink deleteLink,
|
||||
final ActionLink indexLink,
|
||||
final ActionLink orderItemsLink) {
|
||||
final ActionLink deleteLink,
|
||||
final ActionLink indexLink,
|
||||
final ActionLink orderItemsLink) {
|
||||
setHeading(new Label(gz("cms.ui.category.details")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
group.setSubject(new Properties());
|
||||
|
||||
|
||||
group.addAction(new EditVisible(editLink), ActionGroup.EDIT);
|
||||
group.addAction(new EditVisible(orderItemsLink));
|
||||
group.addAction(new EditVisible(indexLink));
|
||||
group.addAction(new AdminVisible(deleteLink), ActionGroup.DELETE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This alternative constructor sets two additional links, allowing the user to view and
|
||||
* edit the content index item.
|
||||
*/
|
||||
SummarySection(final ActionLink editLink,
|
||||
final ActionLink deleteLink,
|
||||
final ActionLink indexLink,
|
||||
final BaseLink viewIndexItem,
|
||||
final BaseLink editIndexItem,
|
||||
final ActionLink orderItemsLink) {
|
||||
final ActionLink deleteLink,
|
||||
final ActionLink indexLink,
|
||||
final BaseLink viewIndexItem,
|
||||
final BaseLink editIndexItem,
|
||||
final ActionLink orderItemsLink) {
|
||||
setHeading(new Label(gz("cms.ui.category.details")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
group.setSubject(new Properties());
|
||||
|
||||
|
||||
group.addAction(new EditVisible(editLink), ActionGroup.EDIT);
|
||||
group.addAction(new EditVisible(orderItemsLink));
|
||||
group.addAction(new EditVisible(indexLink));
|
||||
|
|
@ -220,131 +248,145 @@ class CategoryItemPane extends BaseItemPane {
|
|||
group.addAction(new EditVisible(editIndexItem));
|
||||
group.addAction(new AdminVisible(deleteLink), ActionGroup.DELETE);
|
||||
}
|
||||
|
||||
|
||||
private class Properties extends PropertyList {
|
||||
protected final java.util.List properties(final PageState state) {
|
||||
final java.util.List props = super.properties(state);
|
||||
final Category category = m_category.getCategory(state);
|
||||
final ACSObject item = category.getDirectIndexObject();
|
||||
|
||||
|
||||
String itemTitle = "";
|
||||
|
||||
|
||||
if (item != null) {
|
||||
itemTitle = item.getDisplayName();
|
||||
}
|
||||
|
||||
|
||||
props.add(new Property(gz("cms.ui.name"),
|
||||
category.getName()));
|
||||
category.getName("")));
|
||||
props.add(new Property(gz("cms.ui.description"),
|
||||
category.getDescription()));
|
||||
category.getDescription("")));
|
||||
props.add(new Property(gz("cms.ui.category.url"),
|
||||
category.getURL()));
|
||||
category.getURL("")));
|
||||
props.add(new Property(gz("cms.ui.category.is_not_abstract"),
|
||||
category.isAbstract() ?
|
||||
gz("cms.ui.no") :
|
||||
gz("cms.ui.yes")));
|
||||
category.isAbstract() ?
|
||||
gz("cms.ui.no") :
|
||||
gz("cms.ui.yes")));
|
||||
props.add(new Property(gz("cms.ui.category.is_enabled"),
|
||||
category.isEnabled() ?
|
||||
gz("cms.ui.yes") :
|
||||
gz("cms.ui.no")));
|
||||
category.isEnabled("") ?
|
||||
gz("cms.ui.yes") :
|
||||
gz("cms.ui.no")));
|
||||
props.add(new Property(gz("cms.ui.category.index_item"),
|
||||
itemTitle));
|
||||
|
||||
itemTitle));
|
||||
|
||||
return props;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Quasimodo: BEGIN
|
||||
// CategoryLocalizationSection
|
||||
private class CategoryLocalizationSection extends Section {
|
||||
CategoryLocalizationSection(ActionLink addLink) {
|
||||
setHeading(new Label(gz("cms.ui.category.localizations")));
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
group.setSubject(new CategoryLocalizationTable(m_category, m_model));
|
||||
group.addAction(new AdminVisible(addLink), ActionGroup.ADD);
|
||||
}
|
||||
}
|
||||
|
||||
private class SubcategorySection extends Section {
|
||||
SubcategorySection(final ActionLink addLink) {
|
||||
setHeading(new Label(gz("cms.ui.category.subcategories")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
group.setSubject(new SubcategoryList(m_category, m_model));
|
||||
group.addAction(new AdminVisible(addLink), ActionGroup.ADD);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class LinkedCategorySection extends Section {
|
||||
LinkedCategorySection(final ActionLink linkAddLink) {
|
||||
setHeading(new Label(gz("cms.ui.category.linked")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
group.setSubject(new CategoryLinks(m_category, m_model));
|
||||
group.addAction(new EditVisible(linkAddLink), ActionGroup.EDIT);
|
||||
}
|
||||
|
||||
|
||||
public final boolean isVisible(final PageState state) {
|
||||
return !m_category.getCategory(state).isRoot();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class CategoryTemplateSection extends Section {
|
||||
CategoryTemplateSection() {
|
||||
setHeading(new Label(gz("cms.ui.category.templates")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
group.setSubject(new CategoryTemplates(m_category));
|
||||
// XXX secvis
|
||||
//group.addAction(link);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class PermissionsSection extends Section {
|
||||
public boolean isVisible(PageState ps) {
|
||||
Category cat = m_category.getCategory(ps);
|
||||
return !cat.isRoot() && cat.canAdmin();
|
||||
}
|
||||
|
||||
|
||||
PermissionsSection() {
|
||||
setHeading(new Label(gz("cms.ui.permissions")));
|
||||
|
||||
|
||||
final ActionGroup group = new ActionGroup();
|
||||
setBody(group);
|
||||
|
||||
|
||||
PrivilegeDescriptor[] privs = new PrivilegeDescriptor[] {
|
||||
PrivilegeDescriptor.EDIT,
|
||||
Category.MAP_DESCRIPTOR,
|
||||
PrivilegeDescriptor.DELETE,
|
||||
PrivilegeDescriptor.ADMIN
|
||||
};
|
||||
|
||||
|
||||
HashMap privMap = new HashMap();
|
||||
privMap.put("edit", "Edit");
|
||||
privMap.put("delete", "Delete");
|
||||
privMap.put(Category.MAP_DESCRIPTOR.getName(), "Categorize Items");
|
||||
privMap.put("admin", "Admin");
|
||||
|
||||
|
||||
final CMSPermissionsPane permPane = new CMSPermissionsPane
|
||||
(privs, privMap, new ACSObjectSelectionModel(m_model)) {
|
||||
(privs, privMap, new ACSObjectSelectionModel(m_model)) {
|
||||
public void showAdmin(PageState ps) {
|
||||
Assert.exists(m_model.getSelectedKey(ps));
|
||||
|
||||
|
||||
super.showAdmin(ps);
|
||||
getAdminListingPanel().setVisible(ps, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
final ActionLink restoreDefault = new ActionLink(new Label(gz("cms.ui.restore_default_permissions"))) {
|
||||
public boolean isVisible(PageState ps) {
|
||||
Category cat = m_category.getCategory(ps);
|
||||
return PermissionService.getContext(cat) == null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
final ActionLink useCustom = new ActionLink(new Label(gz("cms.ui.use_custom_permissions"))) {
|
||||
public boolean isVisible(PageState ps) {
|
||||
Category cat = m_category.getCategory(ps);
|
||||
return PermissionService.getContext(cat) != null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ActionListener al = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
PageState state = event.getPageState();
|
||||
|
|
@ -363,18 +405,18 @@ class CategoryItemPane extends BaseItemPane {
|
|||
parent = cat.getDefaultParentCategory();
|
||||
} catch (CategoryNotFoundException ce) {
|
||||
throw new IllegalStateException(
|
||||
"link shouldn't exist for root categories");
|
||||
"link shouldn't exist for root categories");
|
||||
}
|
||||
PermissionService.setContext(cat, parent);
|
||||
|
||||
|
||||
// revoke all direct permissions so category will only
|
||||
// have inherited permissions
|
||||
ObjectPermissionCollection perms =
|
||||
PermissionService.getDirectGrantedPermissions(
|
||||
PermissionService.getDirectGrantedPermissions(
|
||||
cat.getOID());
|
||||
while (perms.next()) {
|
||||
PermissionService.revokePermission(
|
||||
new PermissionDescriptor(
|
||||
new PermissionDescriptor(
|
||||
perms.getPrivilege(), cat.getOID(),
|
||||
perms.getGranteeOID()));
|
||||
}
|
||||
|
|
@ -382,17 +424,17 @@ class CategoryItemPane extends BaseItemPane {
|
|||
permPane.reset(state);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
restoreDefault.addActionListener(al);
|
||||
useCustom.addActionListener(al);
|
||||
|
||||
|
||||
SimpleContainer links = new SimpleContainer();
|
||||
links.add(restoreDefault);
|
||||
links.add(useCustom);
|
||||
|
||||
|
||||
group.setSubject(permPane);
|
||||
group.addAction(links);
|
||||
|
||||
|
||||
m_model.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
PageState ps = e.getPageState();
|
||||
|
|
@ -400,22 +442,22 @@ class CategoryItemPane extends BaseItemPane {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class OrderItemsForm extends CMSForm {
|
||||
|
||||
|
||||
public OrderItemsForm(CategoryRequestLocal category) {
|
||||
super("orderItems", new SimpleContainer());
|
||||
Label header = new Label(gz("cms.ui.category.categorized_objects"));
|
||||
header.setFontWeight(Label.BOLD);
|
||||
add(header);
|
||||
add(new CategorizedObjectsList(category));
|
||||
|
||||
|
||||
add(new Submit("Done"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This private class creates a link to the index item for a category.
|
||||
*/
|
||||
|
|
@ -423,11 +465,11 @@ class CategoryItemPane extends BaseItemPane {
|
|||
ViewItemLink(Component c, String s) {
|
||||
super(c,s);
|
||||
}
|
||||
|
||||
|
||||
// Build the preview link. This uses a standard redirect link to find the content.
|
||||
// The prepareURL method is called by the printwriter
|
||||
protected String prepareURL(final PageState state, String location) {
|
||||
|
||||
|
||||
ContentItem indexItem = ((ContentBundle)(m_category.getCategory(state).getDirectIndexObject())).getPrimaryInstance();
|
||||
if(indexItem==null) {
|
||||
return "";
|
||||
|
|
@ -435,7 +477,7 @@ class CategoryItemPane extends BaseItemPane {
|
|||
return "/redirect/?oid=" + URLEncoder.encode(indexItem.getOID().toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We only show this link when an index item exists for this category
|
||||
public boolean isVisible(PageState state) {
|
||||
if (!super.isVisible(state)) {
|
||||
|
|
@ -449,12 +491,12 @@ class CategoryItemPane extends BaseItemPane {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private class EditItemLink extends Link {
|
||||
EditItemLink(Component c, String s) {
|
||||
super(c,s);
|
||||
}
|
||||
|
||||
|
||||
// Build the preview link. This is based on code in the ContentSoonExpiredPane class.
|
||||
// The prepareURL method of the parent is overwritten. This method is called by the printwriter
|
||||
protected String prepareURL(final PageState state, String location) {
|
||||
|
|
@ -470,7 +512,7 @@ class CategoryItemPane extends BaseItemPane {
|
|||
return "item.jsp?item_id=" + draftID + "&set_tab=" + ContentItemPage.AUTHORING_TAB;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We only show this link when an index item exists for this category and
|
||||
// the user is allowed to edit this item.
|
||||
public boolean isVisible(PageState state) {
|
||||
|
|
@ -484,7 +526,7 @@ class CategoryItemPane extends BaseItemPane {
|
|||
return isItemEditable((ContentItem)indexItem,state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This method checks whether a usern is allowed to edit a particular item
|
||||
private boolean isItemEditable(ContentItem item, PageState state) {
|
||||
BigDecimal id = item.getID();
|
||||
|
|
|
|||
|
|
@ -22,10 +22,13 @@ model com.arsdigita.categorization;
|
|||
import com.arsdigita.kernel.*;
|
||||
|
||||
object type Category extends ACSObject {
|
||||
|
||||
// Hier werden die Default-Werte gespeichert ???
|
||||
String[0..1] description = cat_categories.description VARCHAR(4000);
|
||||
String[1..1] name = cat_categories.name VARCHAR(200);
|
||||
String[0..1] url = cat_categories.url VARCHAR(200);
|
||||
Boolean[1..1] isEnabled = cat_categories.enabled_p CHAR(1);
|
||||
|
||||
Boolean[1..1] isAbstract = cat_categories.abstract_p CHAR(1);
|
||||
String[1..1] defaultAncestors = cat_categories.default_ancestors VARCHAR(3209);
|
||||
Boolean[1..1] ignoreParentIndexItem = cat_categories.ignore_parent_index_p CHAR(1);
|
||||
|
|
@ -33,6 +36,28 @@ object type Category extends ACSObject {
|
|||
reference key (cat_categories.category_id);
|
||||
}
|
||||
|
||||
// locale dependend entries
|
||||
object type CategoryLocalization extends ACSObject {
|
||||
String[1..1] locale = cat_category_localizations.locale CHAR(2);
|
||||
|
||||
// Moved down from Category
|
||||
String[0..1] description = cat_category_localizations.description VARCHAR(4000);
|
||||
String[1..1] name = cat_category_localizations.name VARCHAR(200);
|
||||
String[0..1] url = cat_category_localizations.url VARCHAR(200);
|
||||
Boolean[1..1] isEnabled = cat_category_localizations.enabled_p CHAR(1);
|
||||
|
||||
reference key (cat_category_localizations.id);
|
||||
}
|
||||
|
||||
association {
|
||||
composite Category[1..1] category = join cat_category_localizations.category_id
|
||||
to cat_categories.category_id;
|
||||
|
||||
component CategoryLocalization[0..n] localizations = join cat_categories.category_id
|
||||
to cat_category_localizations.category_id;
|
||||
|
||||
}
|
||||
|
||||
object type UseContext {
|
||||
BigDecimal[1..1] id = cat_root_cat_object_map.id;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* CategorizationConfig.java
|
||||
*
|
||||
* Created on 17. Januar 2008, 15:29
|
||||
*
|
||||
* To change this template, choose Tools | Template Manager
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package com.arsdigita.categorization;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author quasi
|
||||
*/
|
||||
|
||||
import com.arsdigita.runtime.AbstractConfig;
|
||||
import com.arsdigita.runtime.RuntimeConfig;
|
||||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.util.parameter.BooleanParameter;
|
||||
import com.arsdigita.util.parameter.StringParameter;
|
||||
import com.arsdigita.util.parameter.ErrorList;
|
||||
import com.arsdigita.util.parameter.IntegerParameter;
|
||||
import com.arsdigita.util.parameter.Parameter;
|
||||
import com.arsdigita.util.parameter.ParameterError;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Stores the configuration record for the Categorization functionality
|
||||
*/
|
||||
public final class CategorizationConfig extends AbstractConfig {
|
||||
|
||||
private static Logger s_log = Logger.getLogger(CategorizationConfig.class);
|
||||
|
||||
private final Parameter m_showInternalName;
|
||||
private final Parameter m_supportedLanguages;
|
||||
|
||||
public CategorizationConfig() {
|
||||
|
||||
m_showInternalName = new BooleanParameter
|
||||
("waf.categorization.show_internal_name",
|
||||
Parameter.REQUIRED,
|
||||
new Boolean(false));
|
||||
|
||||
m_supportedLanguages = new StringParameter
|
||||
("waf.categorization.supported_languages",
|
||||
Parameter.REQUIRED,
|
||||
"en,de,fr");
|
||||
|
||||
register(m_showInternalName);
|
||||
register(m_supportedLanguages);
|
||||
|
||||
loadInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the showInternalName flag.
|
||||
*/
|
||||
public final boolean getShowInternalName() {
|
||||
return ((Boolean) get(m_showInternalName)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the defaultLanguage flag.
|
||||
*/
|
||||
public final String getDefaultLanguage() {
|
||||
return ((String) get(m_supportedLanguages)).trim().substring(0, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supportedLanguages as StringTokenizer.
|
||||
*/
|
||||
public final StringTokenizer getSupportedLanguages() {
|
||||
return new StringTokenizer((String) get(m_supportedLanguages), ",", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if language lang is part of supported langs
|
||||
*/
|
||||
public final boolean hasLanguage(String lang) {
|
||||
return ((String) get(m_supportedLanguages)).contains(lang);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
waf.categorization.show_internal_name.title=Activate output of internal keys for categorization
|
||||
waf.categorization.show_internal_name.purpose=Activate this setting to output internal keys for categories without the requested locale. This is usually for debugging.
|
||||
waf.categorization.show_internal_name.example=false
|
||||
waf.categorization.show_internal_name.format=[boolean]
|
||||
waf.categorization.supported_languages.title=Set the supported languages for categorization
|
||||
waf.categorization.supported_languages.purpose=Set the supported languages for categorization. First entry is the default language
|
||||
waf.categorization.supported_languages.example=en,de,fr
|
||||
waf.categorization.supported_languages.format=[string]
|
||||
|
|
@ -83,6 +83,24 @@ import org.apache.log4j.Logger;
|
|||
*
|
||||
* @author Randy Graebner
|
||||
* @version $Revision: 1.1 $ $DateTime: $
|
||||
*
|
||||
* <p>Localization is done with some new classes, so the category tree is
|
||||
* now multilanguage. This is completly transparent to the rest of the
|
||||
* system (hopefully) and uses the negotiated language from the browser
|
||||
* environment. The following attributes are localizable:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Name</li>
|
||||
* <li>Description</li>
|
||||
* <li>URL</li>
|
||||
* <li>IsEnabled</li>
|
||||
* </ul>
|
||||
*
|
||||
* To use localized URLs I had to change NavigationFileReolver.resolveCategory()
|
||||
* in ccm-ldn-navigation to filter the categories in Java. There might be other
|
||||
* location in the code where this patch may also be needed. So fix it.
|
||||
*
|
||||
* Quasimodo
|
||||
*/
|
||||
public class Category extends ACSObject {
|
||||
private static final Logger s_log = Logger.getLogger(Category.class);
|
||||
|
|
@ -103,6 +121,14 @@ public class Category extends ACSObject {
|
|||
public static final PrivilegeDescriptor MAP_DESCRIPTOR =
|
||||
new PrivilegeDescriptor("map_to_category");
|
||||
|
||||
// Quasimodo: Begin
|
||||
private static CategorizationConfig s_config = new CategorizationConfig();
|
||||
|
||||
static {
|
||||
s_config.load();
|
||||
}
|
||||
// Quasimodo: End
|
||||
|
||||
public static final String ROOT_CATEGORY = "rootCategory";
|
||||
public static final String USE_CONTEXT = "useContext";
|
||||
public static final String CATEGORY_OWNER = "categoryOwner";
|
||||
|
|
@ -149,6 +175,8 @@ public class Category extends ACSObject {
|
|||
public final static String CHILD_OBJECTS = "childObjects";
|
||||
public final static String RELATED_CATEGORIES = RELATED;
|
||||
public final static String CATEGORIES = "categories";
|
||||
|
||||
public static final String LOCALIZATIONS = "localizations";
|
||||
|
||||
// some named queries in the pdl files
|
||||
private static final String CHILD_CATEGORY_IDS =
|
||||
|
|
@ -158,6 +186,11 @@ public class Category extends ACSObject {
|
|||
|
||||
private HierarchyDenormalization m_hierarchy;
|
||||
|
||||
// Quasimodo: Begin
|
||||
// Save the localized parts of category
|
||||
private CategoryLocalizationCollection m_categoryLocalizationCollection;
|
||||
// Quasimodo: End
|
||||
|
||||
protected String getBaseDataObjectType() {
|
||||
return BASE_DATA_OBJECT_TYPE;
|
||||
}
|
||||
|
|
@ -316,6 +349,15 @@ public class Category extends ACSObject {
|
|||
}
|
||||
|
||||
|
||||
// Quasimodo: Begin
|
||||
|
||||
/**
|
||||
* Retrieves the current configuration
|
||||
*/
|
||||
public static CategorizationConfig getConfig() {
|
||||
return s_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.arsdigita.domain.DomainObject#initialize()
|
||||
*/
|
||||
|
|
@ -334,21 +376,58 @@ public class Category extends ACSObject {
|
|||
setAbstract(false);
|
||||
//by default do not ignore the parent index item
|
||||
setIgnoreParentIndexItem(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
m_hierarchy = new HierarchyDenormalization
|
||||
("com.arsdigita.categorization.updateCategoryDescendants", this,
|
||||
DEFAULT_ANCESTORS) {};
|
||||
}
|
||||
|
||||
m_categoryLocalizationCollection = new CategoryLocalizationCollection(this);
|
||||
|
||||
}
|
||||
// Quasimodo: End
|
||||
|
||||
|
||||
/**
|
||||
* Quasimodo:
|
||||
* Returns the localized name or the name key if localized version don't exist
|
||||
*
|
||||
* @return the category name.
|
||||
*/
|
||||
public String getName(String locale) {
|
||||
|
||||
// Test for localized version
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Return value of isEnabled from localized version, so categories could be disabled depending on locale
|
||||
return m_categoryLocalizationCollection.getName();
|
||||
|
||||
} else {
|
||||
|
||||
// Return name key
|
||||
return (String) get(NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the category name.
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) get(NAME);
|
||||
return getName(this.getNegotiatedLocale());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the display name of the category. This overrides the parent
|
||||
* implementation.
|
||||
* @return the category name.
|
||||
*/
|
||||
public String getDisplayName(String locale) {
|
||||
return getName(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name of the category. This overrides the parent
|
||||
* implementation.
|
||||
|
|
@ -462,17 +541,55 @@ public class Category extends ACSObject {
|
|||
*
|
||||
* @param value the new name of the category
|
||||
*/
|
||||
public void setName(String value) {
|
||||
set(NAME, value);
|
||||
public void setName(String name, String locale) {
|
||||
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
m_categoryLocalizationCollection.getCategoryLocalization().setName(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the category.
|
||||
*
|
||||
* @param value the new name of the category
|
||||
*/
|
||||
public void setName(String name) {
|
||||
set(NAME, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the description of the category.
|
||||
*
|
||||
* Quasimodo:
|
||||
* Returns localized version of description or description key if localized version don't exist
|
||||
*
|
||||
* @return the category description.
|
||||
*/
|
||||
public String getDescription(String locale) {
|
||||
|
||||
// Test for localized version
|
||||
// HACK
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Return value of isEnabled from localized version, so categories could be disabled depending on locale
|
||||
return m_categoryLocalizationCollection.getDescription();
|
||||
|
||||
} else {
|
||||
|
||||
// Return description key
|
||||
return (String) get(DESCRIPTION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the category.
|
||||
* @return the category name.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return (String) get(DESCRIPTION);
|
||||
return getDescription(this.getNegotiatedLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -487,10 +604,47 @@ public class Category extends ACSObject {
|
|||
*
|
||||
* @param value the new description of the category
|
||||
*/
|
||||
public void setDescription(String value) {
|
||||
set(DESCRIPTION, value);
|
||||
public void setDescription(String description, String locale) {
|
||||
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
m_categoryLocalizationCollection.getCategoryLocalization().setDescription(description);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of the category.
|
||||
*
|
||||
* @param value the new description of the category
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
set(DESCRIPTION, description);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the URL component of the category.
|
||||
*
|
||||
* Quasimodo:
|
||||
* Returns the localized version of the URL or URL-key if localized version don't exist
|
||||
*
|
||||
* @return URL component used when browsing categories
|
||||
*/
|
||||
public String getURL(String locale) {
|
||||
|
||||
// Test for localized version
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Return value of isEnabled from localized version, so categories could be disabled depending on locale
|
||||
return m_categoryLocalizationCollection.getURL();
|
||||
|
||||
} else {
|
||||
|
||||
// Return URL-key
|
||||
return (String) get(URL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL component of the category.
|
||||
|
|
@ -498,10 +652,24 @@ public class Category extends ACSObject {
|
|||
* @return URL component used when browsing categories
|
||||
*/
|
||||
public String getURL() {
|
||||
return (String) get(URL);
|
||||
return getURL(this.getNegotiatedLocale());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the URL component of the category.
|
||||
*
|
||||
* @param url URL component used when browsing categories
|
||||
*/
|
||||
public void setURL(String url, String locale) {
|
||||
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
m_categoryLocalizationCollection.getCategoryLocalization().setURL(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the URL component of the category.
|
||||
*
|
||||
|
|
@ -517,11 +685,64 @@ public class Category extends ACSObject {
|
|||
*
|
||||
* @return <code>true</code> if the category is enabled; <code>false</code>
|
||||
* otherwise.
|
||||
*
|
||||
* Quasimodo:
|
||||
* This is getting a bit more compliated:
|
||||
* 1. Check if category is globally disabled
|
||||
* 2. If not, check if localized version exists
|
||||
* 2.1 If so, return isEnabled from localized version
|
||||
* 2.2 If not, return Category.getConfig().getShowInternalName()
|
||||
*
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return ((Boolean) get(IS_ENABLED)).booleanValue();
|
||||
public boolean isEnabled(String locale) {
|
||||
|
||||
// If locale == "" return global status
|
||||
// or if globally disabled, return category as disabled
|
||||
if(locale == "" || ((Boolean) get(IS_ENABLED)).booleanValue() == false) {
|
||||
return ((Boolean) get(IS_ENABLED)).booleanValue();
|
||||
}
|
||||
|
||||
// Test for localized version
|
||||
// HACK
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Return value of isEnabled from localized version, so categories could be disabled depending on locale
|
||||
return m_categoryLocalizationCollection.isEnabled();
|
||||
|
||||
} else {
|
||||
|
||||
// Return value of Category.getConfig().getShowInternalName()
|
||||
// This will disable all categories without selected locale, if Category.getConfig().getShowInternalName() == false
|
||||
return Category.getConfig().getShowInternalName();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the current state of the category.
|
||||
*
|
||||
* @return <code>true</code> if the category is enabled; <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return isEnabled(this.getNegotiatedLocale());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the category is enabled.
|
||||
*
|
||||
* @param isEnabled <code>true</code> if the category is enabled;
|
||||
* <code>false</false> otherwise.
|
||||
*/
|
||||
public void setEnabled(boolean isEnabled, String locale) {
|
||||
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
m_categoryLocalizationCollection.getCategoryLocalization().setEnabled(isEnabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the category is enabled.
|
||||
|
|
@ -1706,6 +1927,11 @@ public class Category extends ACSObject {
|
|||
* @return Array of constituent categories. The first element of the array
|
||||
* is the current category (hence the array will always have length >=
|
||||
* 1). If the path is bad, this returns <code>null</code>.
|
||||
*
|
||||
* This one may be patched to work with localized URLs. I didn't do it for now
|
||||
* because I don't know where it is called and if it's really needed to patch.
|
||||
* Quasimodo
|
||||
*
|
||||
*/
|
||||
public Category[] getChildrenByURL(String path) {
|
||||
final List children = new LinkedList();
|
||||
|
|
@ -1971,4 +2197,103 @@ public class Category extends ACSObject {
|
|||
(new PermissionDescriptor(PrivilegeDescriptor.ADMIN, this,
|
||||
Kernel.getContext().getParty()));
|
||||
}
|
||||
|
||||
// Quasimodo: Begin
|
||||
/**
|
||||
* Getting the negotiated locale from requestContext
|
||||
* @return the negotiated language string if in supported lang list or default language else
|
||||
*/
|
||||
private String getNegotiatedLocale() {
|
||||
|
||||
String locale = null;
|
||||
|
||||
try {
|
||||
|
||||
// Try to get locale from request context
|
||||
locale = com.arsdigita.dispatcher.DispatcherHelper.getRequestContext().getLocale().getLanguage();
|
||||
|
||||
} catch(NullPointerException ex) {
|
||||
|
||||
// If there is no request context (ex. during ccm setup) use default language
|
||||
locale = Category.getConfig().getDefaultLanguage();
|
||||
|
||||
} finally {
|
||||
|
||||
// if supported lang contains locale
|
||||
if(Category.getConfig().hasLanguage(locale)) {
|
||||
|
||||
// then return locale
|
||||
return locale;
|
||||
|
||||
} else {
|
||||
|
||||
// else return default language
|
||||
return Category.getConfig().getDefaultLanguage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CategoryLocalizationCollection getCategoryLocalizationCollection() {
|
||||
return m_categoryLocalizationCollection;
|
||||
}
|
||||
|
||||
public DataAssociation getLocalizations() {
|
||||
return ((DataAssociation) this.get(LOCALIZATIONS));
|
||||
}
|
||||
|
||||
public boolean hasLocalizations() {
|
||||
return !m_categoryLocalizationCollection.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new language set to this category
|
||||
*/
|
||||
public boolean addLanguage(String locale, String name, String description, String url) {
|
||||
|
||||
// If locale don't exist
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && !m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Get DataAssociation
|
||||
DataAssociation categoryLocalizationAssociation = this.getLocalizations();
|
||||
|
||||
// Add association with category
|
||||
(new CategoryLocalization(locale, name, description, url)).addToAssociation(categoryLocalizationAssociation);
|
||||
|
||||
// Reload CategoryLocalizationCollection
|
||||
// this.m_categoryLocalizationCollection = new CategoryLocalizationCollection(this);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a language set from this category
|
||||
*/
|
||||
public boolean delLanguage(String locale) {
|
||||
|
||||
// If locale exist
|
||||
if(locale != "" && m_categoryLocalizationCollection != null && m_categoryLocalizationCollection.localizationExists(locale)) {
|
||||
|
||||
// Get DataAssociation
|
||||
DataAssociation categoryLocalizationAssociation = this.getLocalizations();
|
||||
|
||||
// Remove CategoryLocalization from Association
|
||||
m_categoryLocalizationCollection.getCategoryLocalization().removeFromAssociation(categoryLocalizationAssociation);
|
||||
|
||||
// Reload CategoryLocalizationCollection
|
||||
this.m_categoryLocalizationCollection = new CategoryLocalizationCollection(this);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* CategoryLocalization.java
|
||||
*
|
||||
* Created on 17. Januar 2008, 14:36
|
||||
*
|
||||
* To change this template, choose Tools | Template Manager
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package com.arsdigita.categorization;
|
||||
|
||||
import com.arsdigita.kernel.ACSObject;
|
||||
import com.arsdigita.persistence.DataObject;
|
||||
import com.arsdigita.persistence.OID;
|
||||
import com.arsdigita.persistence.metadata.ObjectType;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author quasi
|
||||
*/
|
||||
public class CategoryLocalization extends ACSObject {
|
||||
|
||||
public static final String BASE_DATA_OBJECT_TYPE = "com.arsdigita.categorization.CategoryLocalization";
|
||||
private static final String BASE_DATA_OBJECT_PACKAGE = "com.arsdigita.categorization";
|
||||
|
||||
// Constants to use in the code
|
||||
public static final String LOCALE = "locale";
|
||||
public static final String NAME = "name";
|
||||
public static final String DESCRIPTION = "description";
|
||||
public static final String URL = "url";
|
||||
public static final String IS_ENABLED = "isEnabled";
|
||||
|
||||
|
||||
protected String getBaseDataObjectType() {
|
||||
return BASE_DATA_OBJECT_TYPE;
|
||||
}
|
||||
|
||||
public static String getBaseDataObjectPackage() {
|
||||
return BASE_DATA_OBJECT_PACKAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the categoryLocalization with the specified data object.
|
||||
*
|
||||
* @param categoryObjectData the data object
|
||||
**/
|
||||
public CategoryLocalization(DataObject categoryLocalizationObjectData) {
|
||||
super(categoryLocalizationObjectData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves as a shortcut to {@link #CategoryLocalization(String)
|
||||
* CategoryLocalization(CategoryLocalization.BASE_DATA_OBJECT_TYPE)}.
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(String)
|
||||
**/
|
||||
public CategoryLocalization() {
|
||||
this(BASE_DATA_OBJECT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the contained data object with a new data object whose object
|
||||
* type is specified by the passed in type name.
|
||||
*
|
||||
* @param typeName the object type for the contained data object
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(String)
|
||||
* @see com.arsdigita.persistence.DataObject
|
||||
* @see com.arsdigita.persistence.metadata.ObjectType
|
||||
**/
|
||||
public CategoryLocalization(String typeName) {
|
||||
super(typeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the contained data object with a new data object whose object
|
||||
* type is the specified type.
|
||||
*
|
||||
* @param type the object type for the contained data object
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(ObjectType)
|
||||
* @see com.arsdigita.persistence.DataObject
|
||||
**/
|
||||
public CategoryLocalization(ObjectType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the data object with the specified OID from the persistent
|
||||
* storage mechanism.
|
||||
*
|
||||
* @param oid the OID for the data object to retrieve
|
||||
* @throws DataObjectNotFoundException if this OID is invalid or has been
|
||||
* deleted.
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(OID)
|
||||
* @see com.arsdigita.persistence.DataObject
|
||||
**/
|
||||
public CategoryLocalization(OID oid) {
|
||||
super(oid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the data object with the specified ID from the persistence
|
||||
* storage mechanism. This method is just a wrapper for the {@link
|
||||
* #CategoryLocalization(OID)} constructor.
|
||||
*
|
||||
* @throws DataObjectNotFoundException
|
||||
*/
|
||||
public CategoryLocalization(BigDecimal id) {
|
||||
this(new OID(BASE_DATA_OBJECT_TYPE, id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new categoryLocalization with the given name and description.
|
||||
*
|
||||
* @param name the name for the new category
|
||||
* @param description the description for the new category
|
||||
*/
|
||||
public CategoryLocalization(String locale, String name, String description) {
|
||||
this();
|
||||
setLocale(locale);
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new categoryLocalization with the given name, description and URL
|
||||
* component.
|
||||
*
|
||||
* @param name the name for the new category
|
||||
* @param description the description for the new category
|
||||
* @param url URL component used when browsing categories.
|
||||
*/
|
||||
public CategoryLocalization(String locale, String name, String description, String url) {
|
||||
this();
|
||||
setLocale(locale);
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
setURL (url);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the categoryLocalization with the given category ID, and sets the name and
|
||||
* description. For the new name and descrption to be permanent, the caller
|
||||
* must call the save() method.
|
||||
*
|
||||
* @param categoryID the category ID
|
||||
* @param name the category name
|
||||
* @param description the category description
|
||||
* @exception DataObjectNotFoundException if this OID is
|
||||
* invalid or has been deleted.
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(OID)
|
||||
*/
|
||||
public CategoryLocalization(OID categoryID, String name, String description) {
|
||||
this(categoryID);
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the categoryLocalization with the given category ID, and sets the name and
|
||||
* description. For the new name and descrption to be permanent, the caller
|
||||
* must call the save() method.
|
||||
*
|
||||
* @param categoryID the category ID
|
||||
* @param name the category name
|
||||
* @param description the category description
|
||||
* @param url URL component used when browsing categories.
|
||||
* @exception DataObjectNotFoundException if this OID is
|
||||
* invalid or has been deleted.
|
||||
*
|
||||
* @see com.arsdigita.domain.DomainObject#DomainObject(OID)
|
||||
*/
|
||||
public CategoryLocalization(OID categoryID, String name, String description, String url) {
|
||||
this(categoryID);
|
||||
setName(name);
|
||||
setDescription(description);
|
||||
setURL (url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see com.arsdigita.domain.DomainObject#initialize()
|
||||
*/
|
||||
protected void initialize() {
|
||||
super.initialize();
|
||||
|
||||
if(isNew()) {
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Getter / Setter methods
|
||||
|
||||
/**
|
||||
* Returns the locale
|
||||
*/
|
||||
public String getLocale() {
|
||||
return (String) get(LOCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale
|
||||
*/
|
||||
private void setLocale(String locale) {
|
||||
set(LOCALE, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized name
|
||||
*/
|
||||
public String getName() {
|
||||
return (String) get(NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set localized name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
set(NAME, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return (String) get(DESCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set localized description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
set(DESCRIPTION, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized URL
|
||||
*/
|
||||
public String getURL() {
|
||||
return (String) get(URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set localized URL
|
||||
*/
|
||||
public void setURL(String url) {
|
||||
set(URL, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized status
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return ((Boolean) get(IS_ENABLED)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set localized status
|
||||
*/
|
||||
public void setEnabled(boolean isEnabled) {
|
||||
set(IS_ENABLED, new Boolean(isEnabled));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* CategoryLocalizationCollection.java
|
||||
*
|
||||
* Created on 19. Januar 2008, 13:24
|
||||
*
|
||||
* Author: Quasimodo
|
||||
*/
|
||||
|
||||
package com.arsdigita.categorization;
|
||||
|
||||
import com.arsdigita.kernel.ACSObject;
|
||||
import com.arsdigita.kernel.ACSObjectCollection;
|
||||
import com.arsdigita.persistence.DataAssociation;
|
||||
import com.arsdigita.persistence.DataCollection;
|
||||
import com.arsdigita.persistence.DataObject;
|
||||
|
||||
/**
|
||||
* Represents a collection of categoryLocalizations.
|
||||
*
|
||||
* <p>Instances of this class are produced by various methods in {@link
|
||||
* Category} and other classes. See, for example, {@link Category#getChildren()}
|
||||
* or {@link Category#getDescendants()}.</p>
|
||||
*
|
||||
* @author Randy Graebner (randyg@alum.mit.edu)
|
||||
* @version $Revision: #15 $ $DateTime: 2004/08/16 18:10:38 $
|
||||
**/
|
||||
public class CategoryLocalizationCollection extends ACSObjectCollection {
|
||||
|
||||
public CategoryLocalizationCollection(Category category) {
|
||||
super(category.getLocalizations().getDataCollection());
|
||||
}
|
||||
|
||||
public CategoryLocalizationCollection(DataCollection dataCollection) {
|
||||
super(dataCollection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale of the categoryLocalization.
|
||||
*
|
||||
* @return the category locale.
|
||||
* @see Category#getLocale()
|
||||
*/
|
||||
public String getLocale() {
|
||||
return getCategoryLocalization().getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the category.
|
||||
*
|
||||
* @return the category name.
|
||||
* @see Category#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return getCategoryLocalization().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description.
|
||||
*
|
||||
* @return the description
|
||||
* @see Category#getDescription()
|
||||
*/
|
||||
public String getDescription() {
|
||||
return getCategoryLocalization().getDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL.
|
||||
*
|
||||
* @return the URL
|
||||
* @see Category#getURL()
|
||||
*/
|
||||
public String getURL() {
|
||||
return getCategoryLocalization().getURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the current state of the category.
|
||||
*
|
||||
* @return <code>true</code> if the category is enabled; <code>false</code>
|
||||
* otherwise.
|
||||
* @see Category#isEnabled()
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return getCategoryLocalization().isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to <code>getDomainObject()</code> that casts the returned
|
||||
* <code>DomainObject</code> as a <code>CategoryLocalization</code>.
|
||||
*
|
||||
* @return a <code>CategoryLocalization</code> for the current position in the
|
||||
* collection.
|
||||
**/
|
||||
public CategoryLocalization getCategoryLocalization() {
|
||||
return (CategoryLocalization) getDomainObject();
|
||||
}
|
||||
|
||||
public ACSObject getACSObject() {
|
||||
return getCategoryLocalization();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the requested localization in the Collection
|
||||
*
|
||||
* @return result of the search. If true, the CollectionCursor is set to the position of the requested locale.
|
||||
*/
|
||||
public boolean localizationExists(String locale) {
|
||||
|
||||
//
|
||||
if(!m_dataCollection.isEmpty() && locale != "") {
|
||||
|
||||
// First check, if we are already at the right position. This will speed up repeated access for the same locale
|
||||
if(this.getPosition() > 0 && this.getCategoryLocalization().getLocale().equals(locale)) return true;
|
||||
|
||||
// Nope, so we have to start a search
|
||||
this.rewind();
|
||||
while(this.next()) {
|
||||
if(this.getCategoryLocalization().getLocale().equals(locale)) return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Not found
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the category collection by the category sort key.
|
||||
*
|
||||
* @see CategorizedCollection#sort(boolean)
|
||||
**/
|
||||
public final void sort(boolean ascending) {
|
||||
if ( ascending ) {
|
||||
addOrder("link.sortKey asc");
|
||||
} else {
|
||||
addOrder("link.sortKey desc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,10 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Diese Klasse ist für die Verabeitung der URLs innerhalb der Anwendung navigation zuständig.
|
||||
*/
|
||||
package com.arsdigita.london.navigation;
|
||||
|
||||
|
||||
|
|
@ -315,7 +319,20 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
|
|||
return NavigationFileResolver.resolveCategory(root, path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* In dieser Methode wird eine URL mit dem Kategorienbaum abgeglichen
|
||||
* und die angeforderte Kategorie zurückgegeben, soweit sie vorhanden
|
||||
* ist.
|
||||
*
|
||||
* Ursprünglich hat diese Methode addEqualsFilter verwendet, um die
|
||||
* passenden Kategorien direkt in der SQL-Abfrage zu filtern. Das ist
|
||||
* aber mit den lokalisierten URL der neuen, lokalisierten Kategorien
|
||||
* nicht mehr möglich - oder zumindest habe ich keinen Weg gefunden.
|
||||
* Stattdessen wird die Filterung nun in Java vorgenommen.
|
||||
*
|
||||
* Quasimodo
|
||||
*/
|
||||
public static Category[] resolveCategory(Category root,
|
||||
String path) {
|
||||
String[] bits = StringUtils.split(path, '/');
|
||||
|
|
@ -333,16 +350,24 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
|
|||
}
|
||||
|
||||
CategoryCollection children = cat.getChildren();
|
||||
children.addEqualsFilter(Category.URL, bits[i]);
|
||||
children.addEqualsFilter(Category.IS_ENABLED, Boolean.TRUE);
|
||||
if (children.next()) {
|
||||
// children.addEqualsFilter(Category.URL, bits[i]);
|
||||
// children.addEqualsFilter(Category.IS_ENABLED, Boolean.TRUE);
|
||||
// if (children.next()) {
|
||||
boolean found = false;
|
||||
while (children.next()) {
|
||||
cat = children.getCategory();
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("Got category " + cat);
|
||||
if(cat.getURL().equals(bits[i]) && cat.isEnabled() == true) {
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("Got category " + cat);
|
||||
}
|
||||
cats.add(cat);
|
||||
children.close();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
cats.add(cat);
|
||||
children.close();
|
||||
} else {
|
||||
}
|
||||
// } else {
|
||||
if(found == false) {
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("No category found ");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue