1   package com.trendmicro.grid.acl.ds.trivial;
2   
3   import com.trendmicro.grid.acl.l0.datatypes.Category;
4   
5   import javax.xml.bind.annotation.*;
6   import java.util.HashMap;
7   import java.util.List;
8   import java.util.Locale;
9   import java.util.Map;
10  
11  /**
12   * Implements an I18N and L10N aware definition of a category.
13   *
14   * @author juergen_kellerer, 2011-01-19
15   * @version 1.0
16   */
17  @XmlType(namespace = I18NAwareDefinition.NS)
18  @XmlAccessorType(XmlAccessType.FIELD)
19  @XmlRootElement(name = "category-definition", namespace = I18NAwareDefinition.NS)
20  public class CategoryDefinition extends I18NAwareDefinition {
21  
22  	@XmlElement(name = "category", required = true)
23  	private Category category;
24  
25  	@XmlElement(name = "displayName")
26  	@XmlElementWrapper(name = "translations")
27  	private List<DisplayName> displayNames;
28  
29  	private transient Map<Locale, Category> localizedCategories;
30  
31  	/**
32  	 * Constructs an empty display name (used by JAXB only).
33  	 */
34  	public CategoryDefinition() {
35  	}
36  
37  	/**
38  	 * Constructs a category definition.
39  	 *
40  	 * @param category		 The category that is defined by this element.
41  	 * @param displayNames	 The localized display names.
42  	 * @param availableLocales The locales that this definition should be made available to.
43  	 */
44  	public CategoryDefinition(Category category, List<DisplayName> displayNames, List<Locale> availableLocales) {
45  		super(availableLocales);
46  		this.category = category;
47  		this.displayNames = displayNames;
48  	}
49  
50  	/**
51  	 * Returns the embedded category.
52  	 *
53  	 * @return the embedded category.
54  	 */
55  	public Category getCategory() {
56  		return category;
57  	}
58  
59  	@Override
60  	public String getName() {
61  		return category.getName();
62  	}
63  
64  	/**
65  	 * Returns a map of all available localized variants of this category.
66  	 *
67  	 * @return a map of all available localized variants of this category.
68  	 */
69  	public Map<Locale, Category> getLocalizedCategories() {
70  		if (localizedCategories == null) {
71  			Map<Locale, Category> lc = new HashMap<Locale, Category>();
72  			for (DisplayName name : displayNames) {
73  				Category c = category.clone().localize(name.getValue(), name.getLocale());
74  				lc.put(name.getLocale(), c);
75  				lc.put(new Locale(name.getLocale().getLanguage()), c);
76  			}
77  			localizedCategories = lc;
78  		}
79  
80  		return localizedCategories;
81  	}
82  
83  	/**
84  	 * Returns a localized version of the category or the default category if no localized version is available.
85  	 *
86  	 * @param locale the locale to use for looking-up a localized category version.
87  	 * @return a localized version of the category or the default category if no localized version is available.
88  	 */
89  	public Category getLocalizedCategory(Locale locale) {
90  		Map<Locale, Category> categories = getLocalizedCategories();
91  
92  		Category category = categories.get(locale);
93  		if (category == null && !locale.getCountry().isEmpty())
94  			category = categories.get(new Locale(locale.getLanguage()));
95  
96  		return category == null ? this.category : category;
97  	}
98  
99  	@Override
100 	public String toString() {
101 		return "CategoryDefinition{" +
102 			"category=" + category +
103 			", displayNames=" + displayNames +
104 			'}';
105 	}
106 
107 	@Override
108 	public boolean equals(Object o) {
109 		if (this == o) return true;
110 		if (!(o instanceof CategoryDefinition)) return false;
111 
112 		CategoryDefinition that = (CategoryDefinition) o;
113 
114 		if (!category.equals(that.category)) return false;
115 		return !(displayNames != null ? !displayNames.equals(that.displayNames) : that.displayNames != null);
116 	}
117 
118 	@Override
119 	public int hashCode() {
120 		int result = category.hashCode();
121 		result = 31 * result + (displayNames != null ? displayNames.hashCode() : 0);
122 		return result;
123 	}
124 }