001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.progmodel.facetdecorators.i18n.resourcebundle.internal;
021
022import java.util.List;
023import java.util.MissingResourceException;
024import java.util.ResourceBundle;
025
026import com.google.common.base.Strings;
027import com.google.common.collect.Lists;
028
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032import org.apache.isis.applib.Identifier;
033import org.apache.isis.core.commons.config.IsisConfiguration;
034import org.apache.isis.core.commons.lang.StringExtensions;
035import org.apache.isis.core.progmodel.facetdecorators.i18n.I18nManager;
036
037/**
038 * REVIEW: why isn't there a type for collections also?
039 */
040public class I18nManagerUsingResourceBundle implements I18nManager {
041
042    private static final Logger LOG = LoggerFactory.getLogger(I18nManagerUsingResourceBundle.class);
043
044    private static final String BASE_FILE_NAME = "i18n";
045
046    private static final String MEMBER_TYPE_PROPERTY = "property";
047    private static final String MEMBER_TYPE_COLLECTION = "collection";
048    private static final String MEMBER_TYPE_ACTION = "action";
049    private static final String MEMBER_TYPE_PARAMETER = "parameter";
050
051    private static final String TEXT_TYPE_NAME = "name";
052    private static final String TEXT_TYPE_DESCRIPTION = "description";
053    private static final String TEXT_TYPE_HELP = "help";
054
055    private ResourceBundle bundle;
056
057    @SuppressWarnings("unused")
058    private final IsisConfiguration configuration;
059
060    // //////////////////////////////////////////////////////////////
061    // Contructor, init, shutdown
062    // //////////////////////////////////////////////////////////////
063
064    public I18nManagerUsingResourceBundle(final IsisConfiguration configuration) {
065        this.configuration = configuration;
066    }
067
068    @Override
069    public void init() {
070        try {
071            bundle = ResourceBundle.getBundle(BASE_FILE_NAME);
072        } catch (final MissingResourceException e) {
073            LOG.warn("Missing resource bundle: " + e.getMessage());
074        }
075
076    }
077
078    @Override
079    public void shutdown() {
080    }
081
082    // //////////////////////////////////////////////////////////////
083    // Members
084    // //////////////////////////////////////////////////////////////
085
086    @Override
087    public String getName(final Identifier identifier) {
088        return internalizedTextForClassMember(identifier, TEXT_TYPE_NAME);
089    }
090
091    @Override
092    public String getDescription(final Identifier identifier) {
093        return internalizedTextForClassMember(identifier, TEXT_TYPE_DESCRIPTION);
094    }
095
096    @Override
097    public String getHelp(final Identifier identifier) {
098        return internalizedTextForClassMember(identifier, TEXT_TYPE_HELP);
099    }
100
101    private String internalizedTextForClassMember(final Identifier identifier, final String textType) {
102        if (bundle == null) {
103            return null;
104        }
105        final List<String> key = buildMemberTypeKey(identifier, textType);
106        return lookupTextFromBundle(key);
107    }
108
109    private static List<String> buildMemberTypeKey(final Identifier identifier, final String textType) {
110        final List<String> keys = Lists.newArrayList();
111
112        if (identifier.isPropertyOrCollection()) {
113            keys.add(buildMemberTypeKey(identifier, textType, MEMBER_TYPE_PROPERTY));
114            keys.add(buildMemberTypeKey(identifier, textType, MEMBER_TYPE_COLLECTION));
115        } else {
116            keys.add(buildMemberTypeKey(identifier, textType, MEMBER_TYPE_ACTION));
117        }
118        return keys;
119    }
120
121    private static String buildMemberTypeKey(final Identifier identifier, final String textType, final String memberType) {
122        final StringBuilder sb = new StringBuilder();
123        sb.append(identifier.getClassName()).append(".");
124        sb.append(memberType);
125        final String memberName = identifier.getMemberName();
126        if (!Strings.isNullOrEmpty(memberName)) {
127            sb.append(".").append(memberName);
128        }
129        sb.append(".").append(textType);
130        return sb.toString();
131    }
132
133    // //////////////////////////////////////////////////////////////
134    // Parameters
135    // //////////////////////////////////////////////////////////////
136
137    @Override
138    public List<String> getParameterNames(final Identifier identifier) {
139        return internalizedTextForParameter(identifier, TEXT_TYPE_NAME);
140    }
141
142    private List<String> internalizedTextForParameter(final Identifier identifier, final String textType) {
143        if (bundle == null) {
144            return null;
145        }
146        final List<String> internalizedText = Lists.newArrayList();
147        final List<String> memberParameterNames = identifier.getMemberParameterNames();
148        int paramNum = 0;
149        for (@SuppressWarnings("unused")
150        final String dummy : memberParameterNames) {
151            final String key = buildParameterTypeKey(identifier, textType, paramNum);
152            internalizedText.add(lookupTextFromBundle(key));
153            paramNum++;
154        }
155        return internalizedText;
156    }
157
158    private static String buildParameterTypeKey(final Identifier identifier, final String textType, final int paramNum) {
159        return identifier.getClassName() + "." + MEMBER_TYPE_ACTION + "." + identifier.getMemberName() + "." + MEMBER_TYPE_PARAMETER + (paramNum + 1) + "." + textType;
160    }
161
162    // //////////////////////////////////////////////////////////////
163    // Helpers
164    // //////////////////////////////////////////////////////////////
165
166    private String lookupTextFromBundle(final List<String> keys) {
167        for (final String key : keys) {
168            final String text = lookupTextFromBundle(key);
169            if (text != null) {
170                return text;
171            }
172        }
173        return null;
174    }
175
176    private String lookupTextFromBundle(final String key) {
177        try {
178            return bundle.getString(key);
179        } catch (final MissingResourceException e) {
180            return null;
181        }
182    }
183
184}