Skip to content

Commit

Permalink
Adapt bundle-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cuioss committed Oct 12, 2023
1 parent eef54fd commit 61fe1bc
Show file tree
Hide file tree
Showing 21 changed files with 1,289 additions and 177 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;

import de.cuioss.portal.common.bundle.PortalResourceBundleLocator;
import de.cuioss.portal.common.bundle.ResourceBundleLocator;
import de.cuioss.portal.common.priority.PortalPriorities;
import lombok.EqualsAndHashCode;
Expand All @@ -31,12 +30,12 @@

/**
* Defines the base bundles to be defined within a portal application, that are
* "de.cuioss.portal.ui.i18n.portal-messages", "de.cuioss.jsf.api.core.l18n.messages" with the Priority
* "de.cuioss.portal.ui.i18n.portal-messages",
* "de.cuioss.jsf.api.core.l18n.messages" with the Priority
* {@link PortalPriorities#PORTAL_CORE_LEVEL}
*
* @author Matthias Walliczek
*/
@PortalResourceBundleLocator
@Priority(PortalPriorities.PORTAL_CORE_LEVEL)
@ApplicationScoped
@EqualsAndHashCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;

import de.cuioss.portal.common.bundle.PortalResourceBundleLocator;
import de.cuioss.portal.common.bundle.ResourceBundleLocator;
import de.cuioss.portal.common.priority.PortalPriorities;
import de.cuioss.tools.logging.CuiLogger;
Expand All @@ -42,7 +41,6 @@
*
* @author Matthias Walliczek
*/
@PortalResourceBundleLocator
@Priority(PortalPriorities.PORTAL_ASSEMBLY_LEVEL + 10)
@ApplicationScoped
@EqualsAndHashCode
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.cuioss.portal.common.bundle;

import java.io.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.ResourceBundle;
import java.util.Set;

import javax.faces.application.Application;
import javax.inject.Inject;

import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
* <p>
* Portal variant of {@link ResourceBundle}. It delegates to
* {@link ResourceBundleWrapper} that does the actual heavy lifting.
* </p>
* <p>
* It usage is for cases where there is technically a {@link ResourceBundle}
* needed. Sadly there is no corresponding interface, solely an Abstract-Class
* that can not be proxied by CDI. Currently it's sole use is the context of the
* PortalApplication, that it exposes it on
* {@link Application#getResourceBundle(javax.faces.context.FacesContext, String)}
* with the name "msgs"
*
* It can be used directly in jsf views: {@code #{msgs['page.401.title']}}
* </p>
*
* @author Oliver Wolff
*/
@EqualsAndHashCode(callSuper = false)
@ToString
public class PortalResourceBundleBean extends ResourceBundle implements Serializable {

private static final long serialVersionUID = 3953649686127640297L;

/** Lookup name for el-expression within views: "msgs" */
public static final String BUBDLE_NAME = "msgs";

@Inject
private ResourceBundleWrapper resourceBundleWrapper;

private String allBundleNames;

@Override
protected Object handleGetObject(final String key) {
return resourceBundleWrapper.getString(key);
}

@Override
public Enumeration<String> getKeys() {
return Collections.enumeration(keySet());
}

@Override
public Set<String> keySet() {
return resourceBundleWrapper.keySet();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import javax.annotation.Priority;

/**
* Utilized for configuring ResourceBundles. implementations should provide a
* Used for configuring ResourceBundles. Implementations should provide a
* {@link Priority}. Because of the overwriting mechanics a higher
* {@link Priority} of one of the concrete bundles results in a higher priority
* of said bundles, resulting in the key to be chosen of the ones with the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,86 @@
*/
package de.cuioss.portal.common.bundle;

import static de.cuioss.tools.collect.CollectionLiterals.mutableList;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.annotation.PostConstruct;
import javax.annotation.Priority;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import de.cuioss.portal.common.priority.PortalPriorities;
import de.cuioss.tools.collect.CollectionLiterals;
import de.cuioss.tools.logging.CuiLogger;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

/**
* Registry for the ResourceBundleNames. Provides the resulting list of
* configured resource bundles ordered by priority.
* Registry for the ResourceBundleNames. The injected
* {@link ResourceBundleLocator}s must have unique paths and define an existing
* {@link ResourceBundle}. In addition they should be annotated with the
* corresponding {@link Priority}
*
* @author Matthias Walliczek
* @author Oliver Wolff
*/
public interface ResourceBundleRegistry extends Serializable {
@ApplicationScoped
@EqualsAndHashCode(of = "resolvedPaths", doNotUseGetters = true)
@ToString(of = "resolvedPaths", doNotUseGetters = true)
public class ResourceBundleRegistry implements Serializable {

private static final long serialVersionUID = 2611987921899581695L;

private static final CuiLogger log = new CuiLogger(ResourceBundleRegistry.class);

/** "Portal-506: Duplicate ResourceBundlePath found for '{}'" */
public static final String ERR_DUPLICATE_RESOURCE_PATH = "Portal-506: Duplicate ResourceBundlePath found for '{}'";

/** "Portal-507: No ResourceBundle found with path " */
public static final String ERR_NO_RESOURCE_FOUND = "Portal-507: No ResourceBundle found with path ";

@Inject
Instance<ResourceBundleLocator> locatorList;

/**
* The computed / resolved names in the correct order
*/
@Getter
private List<String> resolvedPaths;

/**
* @return The computed / resolved names in the correct order
* Initializes the bean. See class documentation for expected result.
*/
List<String> getResolvedPaths();
@PostConstruct
void initBean() {

var defaultLocale = Locale.getDefault();
final List<String> finalPaths = new ArrayList<>();
// Sort according to ResourceBundleDescripor#order
final List<ResourceBundleLocator> sortedLocators = PortalPriorities.sortByPriority(mutableList(locatorList));
for (final ResourceBundleLocator descriptor : sortedLocators) {
for (final String path : descriptor.getConfiguredResourceBundles()) {
// Check whether the path defines an existing ResourceBundle
try {
ResourceBundle.getBundle(path, defaultLocale);
// Check whether path is unique
if (finalPaths.contains(path)) {
log.error(ERR_DUPLICATE_RESOURCE_PATH, path);
}
finalPaths.add(path);
} catch (MissingResourceException e) {
log.error(ERR_NO_RESOURCE_FOUND + path, e);
}
}
}
resolvedPaths = CollectionLiterals.immutableList(finalPaths);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.cuioss.portal.common.bundle;

import java.io.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;

/**
* Defines the portal-contract dealing with UnifiedResourceBundle Technically it
* provides an interface similar to {@link ResourceBundle}
*
* @author Oliver Wolff
*/
public interface ResourceBundleWrapper extends Serializable {

/**
* Returns resolved message by given key.
*
* @param key to be looked up
* @return the resolved message if key is defined, otherwise "??[key value]??"
* will be returned and warning will be written
* @throws MissingResourceException if key is unknown and application is in
* development mode
*/
String getString(String key);

/**
* Technical method for {@link ResourceBundle} caching the resolved keys and
* values @see {@link ResourceBundle#getKeys()}
*
* @return an Enumeration of the keys contained in this ResourceBundle and its
* parent bundles.
*/
default Enumeration<String> getKeys() {
return Collections.enumeration(keySet());
}

/**
* @return set of all supported keys of this bundle
*/
Set<String> keySet();

/**
* @return a list of all configured bundles to be used for debugging.
*/
String getBundleContent();

}
Loading

0 comments on commit 61fe1bc

Please sign in to comment.