001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.core.util.resource.locator;
018
019import java.util.Iterator;
020import java.util.Locale;
021
022import org.apache.wicket.util.string.Strings;
023
024
025/**
026 * Given a Locale it'll iterate over all possible combinations of the attrs making up the Locale.
027 * Starting the Locale provided to more 'weaker' combinations. The latest one will be no Locale in
028 * which case an empty string will be returned.
029 *
030 * @author Juergen Donnerstag
031 */
032public class LocaleResourceNameIterator implements Iterator<String>
033{
034        /** The locale (see Session) */
035        private final Locale locale;
036
037        /** Internal state */
038        private int state = 0;
039
040        private final boolean strict;
041
042        /**
043         * Construct.
044         *
045         * @param locale
046         * @param strict
047         */
048        public LocaleResourceNameIterator(final Locale locale, boolean strict)
049        {
050                this.locale = locale;
051                this.strict = strict;
052        }
053
054        /**
055         * @return Locale
056         */
057        public Locale getLocale()
058        {
059                if (state == 1)
060                {
061                        // Language, country, variation
062                        return locale;
063                }
064                else if (state == 2)
065                {
066                        return new Locale(locale.getLanguage(), locale.getCountry());
067                }
068                else if (state == 3)
069                {
070                        return new Locale(locale.getLanguage());
071                }
072                return null;
073        }
074
075        /**
076         *
077         * @see java.util.Iterator#hasNext()
078         */
079        @Override
080        public boolean hasNext()
081        {
082                int limit = 4;
083                if (strict && locale != null)
084                {
085                        // omit the last step
086                        limit = 3;
087                }
088                return (state < limit);
089        }
090
091        /**
092         * @see java.util.Iterator#next()
093         */
094        @Override
095        public String next()
096        {
097                if (locale == null)
098                {
099                        state = 999;
100                        return "";
101                }
102
103                // Get language and country, either of which may be the empty string
104                final String language = locale.getLanguage();
105                final String country = locale.getCountry();
106                final String variant = locale.getVariant();
107
108                // 1. If variant are available
109                if (state == 0)
110                {
111                        state++;
112                        if (!Strings.isEmpty(variant))
113                        {
114                                return '_' + language + '_' + country + '_' + variant;
115                        }
116                }
117
118
119                // 2. If country available
120                if (state == 1)
121                {
122                        state++;
123
124                        if (!Strings.isEmpty(country))
125                        {
126                                return '_' + language + '_' + country;
127                        }
128                }
129
130
131                // 4. If language is available
132                if (state == 2)
133                {
134                        state++;
135                        if (!Strings.isEmpty(language))
136                        {
137                                return '_' + language;
138                        }
139                }
140
141                // 4. The path only; without locale
142                state++;
143                return "";
144        }
145
146        /**
147         *
148         * @see java.util.Iterator#remove()
149         */
150        @Override
151        public void remove()
152        {
153        }
154}