Mappings.java revision 6548:7dcb74c3ffba
150476Speter/*
282486Sbde * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3139761Skrion * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4139761Skrion *
521611Swosch * This code is free software; you can redistribute it and/or modify it
618052Sbde * under the terms of the GNU General Public License version 2 only, as
794940Sru * published by the Free Software Foundation.  Oracle designates this
894940Sru * particular file as subject to the "Classpath" exception as provided
994940Sru * by Oracle in the LICENSE file that accompanied this code.
1094940Sru *
1136494Sbde * This code is distributed in the hope that it will be useful, but WITHOUT
1218052Sbde * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1336494Sbde * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14125762Skientzle * version 2 for more details (a copy is included in the LICENSE file that
15125255Sbde * accompanied this code).
1639412Sphk *
17186647Srwatson * You should have received a copy of the GNU General Public License version
18168418Spjd * 2 along with this work; if not, write to the Free Software Foundation,
19135771Strhodes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20156813Sru *
21135549Sdes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22135549Sdes * or visit www.oracle.com if you need additional information or have any
23135599Sru * questions.
24125256Sbde */
25117183Sru
26155211Srwatsonimport  java.util.ArrayList;
27122404Shartiimport  java.util.HashMap;
2879495Sobrienimport  java.util.LinkedList;
2936494Sbdeimport  java.util.List;
3076515Sbdeimport  java.util.Map;
3136494Sbdeimport  java.util.Set;
3239259Sgibbsimport  java.util.TreeMap;
3376515Sbdeimport  java.util.TreeSet;
3436494Sbde
3536494Sbde/**
36125255Sbde * <code>Mappings</code> generates two Maps and a List which are used by
37179184Sjb * javazic BackEnd.
3836494Sbde *
3976515Sbde * @since 1.4
4039259Sgibbs */
4136494Sbdeclass Mappings {
4236494Sbde    // All aliases specified by Link statements. It's alias name to
43135549Sdes    // real name mappings.
44179184Sjb    private Map<String,String> aliases;
45179184Sjb
4636494Sbde    private List<Integer> rawOffsetsIndex;
47176439Sru
4874535Sdes    private List<Set<String>> rawOffsetsIndexTable;
4918052Sbde
5076515Sbde    // Zone names to be excluded from rawOffset table. Those have GMT
5136494Sbde    // offsets to change some future time.
5276515Sbde    private List<String> excludeList;
5336494Sbde
54116318Speter    /**
55112461Sru     * Constructor creates some necessary instances.
5636494Sbde     */
57125255Sbde    Mappings() {
58178828Sdfr        aliases = new TreeMap<String,String>();
59125255Sbde        rawOffsetsIndex = new LinkedList<Integer>();
6047570Sache        rawOffsetsIndexTable = new LinkedList<Set<String>>();
61178828Sdfr    }
62178828Sdfr
6357538Sshin    /**
64156905Sru     * Generates aliases and rawOffsets tables.
6536494Sbde     * @param zi a Zoneinfo containing Zones
66156905Sru     */
67156813Sru    void add(Zoneinfo zi) {
6867523Sarchie        Map<String,Zone> zones = zi.getZones();
69135549Sdes
70135549Sdes        for (String zoneName : zones.keySet()) {
71135599Sru            Zone zone = zones.get(zoneName);
72194869Sjamie            String zonename = zone.getName();
73125255Sbde            int rawOffset = zone.get(zone.size()-1).getGmtOffset();
74125255Sbde
75125255Sbde            // If the GMT offset of this Zone will change in some
76104465Sru            // future time, this Zone is added to the exclude list.
77120492Sfjoe            boolean isExcluded = false;
78125255Sbde            for (int i = 0; i < zone.size(); i++) {
7936494Sbde                ZoneRec zrec = zone.get(i);
8036494Sbde                if ((zrec.getGmtOffset() != rawOffset)
8165916Sache                    && (zrec.getUntilTime(0) > Time.getCurrentTime())) {
82156813Sru                    if (excludeList == null) {
83135599Sru                        excludeList = new ArrayList<String>();
84135599Sru                    }
8536494Sbde                    excludeList.add(zone.getName());
86133362Sobrien                    isExcluded = true;
8736494Sbde                    break;
88148100Srwatson                }
8976515Sbde            }
90156813Sru
9190796Sgshapiro            if (!rawOffsetsIndex.contains(new Integer(rawOffset))) {
9290796Sgshapiro                // Find the index to insert this raw offset zones
9336494Sbde                int n = rawOffsetsIndex.size();
94156905Sru                int i;
9552251Sbp                for (i = 0; i < n; i++) {
96156905Sru                    if (rawOffsetsIndex.get(i) > rawOffset) {
9736494Sbde                        break;
98167359Srafan                    }
9952419Sjulian                }
100121615Sharti                rawOffsetsIndex.add(i, rawOffset);
101168407Spjd
10236494Sbde                Set<String> perRawOffset = new TreeSet<String>();
10336494Sbde                if (!isExcluded) {
10442916Sjdp                    perRawOffset.add(zonename);
10542916Sjdp                }
106107256Sru                rawOffsetsIndexTable.add(i, perRawOffset);
10759770Sbde            } else if (!isExcluded) {
108125381Sru                int i = rawOffsetsIndex.indexOf(new Integer(rawOffset));
109107256Sru                Set<String> perRawOffset = rawOffsetsIndexTable.get(i);
110156813Sru                perRawOffset.add(zonename);
111178828Sdfr            }
112125381Sru        }
113178828Sdfr
11476576Smarkm        Map<String,String> a = zi.getAliases();
115125381Sru        // If there are time zone names which refer to any of the
116137675Sbz        // excluded zones, add those names to the excluded list.
117125381Sru        if (excludeList != null) {
118137675Sbz            for (String zoneName : a.keySet()) {
119156813Sru                String realname = a.get(zoneName);
120125381Sru                if (excludeList.contains(realname)) {
121125381Sru                    excludeList.add(zoneName);
12242916Sjdp                }
123156813Sru            }
124137675Sbz        }
125137675Sbz        aliases.putAll(a);
12689705Sru    }
127137675Sbz
12842916Sjdp    /**
12976515Sbde     * Adds valid aliases to one of per-RawOffset table and removes
13036494Sbde     * invalid aliases from aliases List. Aliases referring to
131145256Sjkoshy     * excluded zones are not added to a per-RawOffset table.
132179184Sjb     */
133172401Sru    void resolve() {
13441231Sjdp        int index = rawOffsetsIndexTable.size();
13536494Sbde        List<String> toBeRemoved = new ArrayList<String>();
136125255Sbde        for (String key : aliases.keySet()) {
13736494Sbde            boolean validname = false;
138125256Sbde            for (int j = 0; j < index; j++) {
139121054Semax                Set<String> perRO = rawOffsetsIndexTable.get(j);
14088142Sru                boolean isExcluded = (excludeList == null) ?
141125255Sbde                                        false : excludeList.contains(key);
142125255Sbde
143125537Sru                if ((perRO.contains(aliases.get(key)) || isExcluded)
14436494Sbde                    && Zone.isTargetZone(key)) {
14541231Sjdp                    validname = true;
14636494Sbde                    if (!isExcluded) {
14718052Sbde                        perRO.add(key);
14876515Sbde                        Main.info("Alias <"+key+"> added to the list.");
149109725Sru                    }
150101224Srwatson                    break;
151168407Spjd                }
152104465Sru            }
153201920Santoine
154200062Sed            if (!validname) {
15536494Sbde                Main.info("Alias <"+key+"> removed from the list.");
156168407Spjd                toBeRemoved.add(key);
15776515Sbde            }
15844757Smarkm        }
15936494Sbde
16036494Sbde        // Remove zones, if any, from the list.
16194578Sdes        for (String key : toBeRemoved) {
16236494Sbde            aliases.remove(key);
163168407Spjd        }
164168407Spjd        // Eliminate any alias-to-alias mappings. For example, if
165        // there are A->B and B->C, A->B is changed to A->C.
166        Map<String, String> newMap = new HashMap<String, String>();
167        for (String key : aliases.keySet()) {
168            String realid = aliases.get(key);
169            String leaf = realid;
170            while (aliases.get(leaf) != null) {
171                leaf = aliases.get(leaf);
172            }
173            if (!realid.equals(leaf)) {
174                newMap.put(key, leaf);
175            }
176        }
177        aliases.putAll(newMap);
178    }
179
180    Map<String,String> getAliases() {
181        return(aliases);
182    }
183
184    List<Integer> getRawOffsetsIndex() {
185        return(rawOffsetsIndex);
186    }
187
188    List<Set<String>> getRawOffsetsIndexTable() {
189        return(rawOffsetsIndexTable);
190    }
191
192    List<String> getExcludeList() {
193        return excludeList;
194    }
195}
196