1   package com.trendmicro.grid.acl.ds.trivial;
2   
3   import com.trendmicro.grid.acl.ds.CategoryRepository;
4   import com.trendmicro.grid.acl.l0.datatypes.Category;
5   import com.trendmicro.grid.acl.l0.datatypes.CategoryView;
6   
7   import javax.xml.bind.annotation.*;
8   import java.util.ArrayList;
9   import java.util.List;
10  import java.util.Locale;
11  
12  /**
13   * Implements a persistable data structure that is capable of defining category views.
14   *
15   * @author juergen_kellerer, 2010-05-06
16   * @version 1.0
17   */
18  @XmlType(namespace = I18NAwareDefinition.NS)
19  @XmlAccessorType(XmlAccessType.FIELD)
20  @XmlRootElement(name = "category-view-definition", namespace = I18NAwareDefinition.NS)
21  public class CategoryViewDefinition extends I18NAwareDefinition {
22  
23  	private static final Category[] EMPTY_CHILDREN = new Category[0];
24  
25  	@XmlAttribute
26  	String name;
27  
28  	@XmlElement(name = "category")
29  	private List<CategoryViewDefinition> children = new ArrayList<CategoryViewDefinition>();
30  
31  	/**
32  	 * Constructs an empty category view definition (used by JAXB only).
33  	 */
34  	public CategoryViewDefinition() {
35  	}
36  
37  	/**
38  	 * Constructs a display name.
39  	 *
40  	 * @param name			 The unique name of the view.
41  	 * @param availableLocales the locales that his view should be made available in.
42  	 */
43  	public CategoryViewDefinition(String name, List<Locale> availableLocales) {
44  		super(availableLocales);
45  		this.name = name;
46  	}
47  
48  	public String getName() {
49  		return name;
50  	}
51  
52  	public List<CategoryViewDefinition> getChildren() {
53  		return children;
54  	}
55  
56  	/**
57  	 * Converts this definition to a localized category view.
58  	 *
59  	 * @param locale			 the locale to use for L10N and I18N.
60  	 * @param categoryRepository the implementation delivering the categories.
61  	 * @return a localized category view.
62  	 */
63  	public CategoryView toCategoryView(Locale locale, CategoryRepository categoryRepository) {
64  		try {
65  			return new CategoryView(name, createChildCategories(locale, categoryRepository));
66  		} catch (IllegalStateException e) {
67  			throw new IllegalStateException("Failed assembling the category view '" + name + "'", e);
68  		}
69  	}
70  
71  	private Category toCategoryTree(Locale locale, CategoryRepository categoryRepository) {
72  		Category c = categoryRepository.getPlainCategory(locale, name);
73  		if (c == null) {
74  			throw new IllegalStateException(
75  				"Failed to retrieve category '" + name + "' from the given category repository.");
76  		}
77  		c.setChildCategories(createChildCategories(locale, categoryRepository));
78  		return c;
79  	}
80  
81  	private Category[] createChildCategories(Locale locale, CategoryRepository categoryRepository) {
82  		if (!children.isEmpty()) {
83  			List<Category> childCategories = new ArrayList<Category>(children.size());
84  			for (CategoryViewDefinition definition : children) {
85  				if (definition.isAvailableInLocale(locale))
86  					childCategories.add(definition.toCategoryTree(locale, categoryRepository));
87  			}
88  			return childCategories.toArray(new Category[childCategories.size()]);
89  		}
90  		return EMPTY_CHILDREN;
91  	}
92  }