1.1 --- a/src/net/fortuna/ical4j/model/TimeZoneRegistryImpl.java Thu Feb 12 18:02:00 2015 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,225 +0,0 @@ 1.4 -/** 1.5 - * Copyright (c) 2012, Ben Fortuna 1.6 - * All rights reserved. 1.7 - * 1.8 - * Redistribution and use in source and binary forms, with or without 1.9 - * modification, are permitted provided that the following conditions 1.10 - * are met: 1.11 - * 1.12 - * o Redistributions of source code must retain the above copyright 1.13 - * notice, this list of conditions and the following disclaimer. 1.14 - * 1.15 - * o Redistributions in binary form must reproduce the above copyright 1.16 - * notice, this list of conditions and the following disclaimer in the 1.17 - * documentation and/or other materials provided with the distribution. 1.18 - * 1.19 - * o Neither the name of Ben Fortuna nor the names of any other contributors 1.20 - * may be used to endorse or promote products derived from this software 1.21 - * without specific prior written permission. 1.22 - * 1.23 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1.27 - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1.28 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1.29 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 1.30 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 1.31 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1.32 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1.33 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 - */ 1.35 -package net.fortuna.ical4j.model; 1.36 - 1.37 -import java.io.IOException; 1.38 -import java.net.URL; 1.39 -import java.util.Map; 1.40 -import java.util.Properties; 1.41 -import java.util.regex.Matcher; 1.42 -import java.util.regex.Pattern; 1.43 - 1.44 -import net.fortuna.ical4j.data.CalendarBuilder; 1.45 -import net.fortuna.ical4j.data.ParserException; 1.46 -import net.fortuna.ical4j.model.component.VTimeZone; 1.47 -import net.fortuna.ical4j.model.property.TzUrl; 1.48 -import net.fortuna.ical4j.util.CompatibilityHints; 1.49 -import net.fortuna.ical4j.util.Configurator; 1.50 -import net.fortuna.ical4j.util.ResourceLoader; 1.51 - 1.52 -import org.apache.commons.logging.Log; 1.53 -import org.apache.commons.logging.LogFactory; 1.54 - 1.55 -import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; 1.56 - 1.57 -/** 1.58 - * $Id$ 1.59 - * 1.60 - * Created on 18/09/2005 1.61 - * 1.62 - * The default implementation of a <code>TimeZoneRegistry</code>. This implementation will search the classpath for 1.63 - * applicable VTimeZone definitions used to back the provided TimeZone instances. 1.64 - * @author Ben Fortuna 1.65 - */ 1.66 -public class TimeZoneRegistryImpl implements TimeZoneRegistry { 1.67 - 1.68 - private static final String DEFAULT_RESOURCE_PREFIX = "zoneinfo/"; 1.69 - 1.70 - private static final Pattern TZ_ID_SUFFIX = Pattern.compile("(?<=/)[^/]*/[^/]*$"); 1.71 - 1.72 - private static final String UPDATE_ENABLED = "net.fortuna.ical4j.timezone.update.enabled"; 1.73 - 1.74 - private static final Map DEFAULT_TIMEZONES = new ConcurrentHashMap(); 1.75 - 1.76 - private static final Properties ALIASES = new Properties(); 1.77 - static { 1.78 - try { 1.79 - ALIASES.load(ResourceLoader.getResourceAsStream("tz.alias")); 1.80 - } 1.81 - catch (IOException ioe) { 1.82 - LogFactory.getLog(TimeZoneRegistryImpl.class).warn( 1.83 - "Error loading timezone aliases: " + ioe.getMessage()); 1.84 - } 1.85 - try { 1.86 - ALIASES.load(ResourceLoader.getResourceAsStream("/tz.alias")); 1.87 - } 1.88 - catch (Exception e) { 1.89 - LogFactory.getLog(TimeZoneRegistryImpl.class).debug( 1.90 - "Error loading custom timezone aliases: " + e.getMessage()); 1.91 - } 1.92 - } 1.93 - 1.94 - private Map timezones; 1.95 - 1.96 - private String resourcePrefix; 1.97 - 1.98 - /** 1.99 - * Default constructor. 1.100 - */ 1.101 - public TimeZoneRegistryImpl() { 1.102 - this(DEFAULT_RESOURCE_PREFIX); 1.103 - } 1.104 - 1.105 - /** 1.106 - * Creates a new instance using the specified resource prefix. 1.107 - * @param resourcePrefix a prefix prepended to classpath resource lookups for default timezones 1.108 - */ 1.109 - public TimeZoneRegistryImpl(final String resourcePrefix) { 1.110 - this.resourcePrefix = resourcePrefix; 1.111 - timezones = new ConcurrentHashMap(); 1.112 - } 1.113 - 1.114 - /** 1.115 - * {@inheritDoc} 1.116 - */ 1.117 - public final void register(final TimeZone timezone) { 1.118 - // for now we only apply updates to included definitions by default.. 1.119 - register(timezone, false); 1.120 - } 1.121 - 1.122 - /** 1.123 - * {@inheritDoc} 1.124 - */ 1.125 - public final void register(final TimeZone timezone, boolean update) { 1.126 - if (update) { 1.127 - // load any available updates for the timezone.. 1.128 - timezones.put(timezone.getID(), new TimeZone(updateDefinition(timezone.getVTimeZone()))); 1.129 - } 1.130 - else { 1.131 - timezones.put(timezone.getID(), timezone); 1.132 - } 1.133 - } 1.134 - 1.135 - /** 1.136 - * {@inheritDoc} 1.137 - */ 1.138 - public final void clear() { 1.139 - timezones.clear(); 1.140 - } 1.141 - 1.142 - /** 1.143 - * {@inheritDoc} 1.144 - */ 1.145 - public final TimeZone getTimeZone(final String id) { 1.146 - TimeZone timezone = (TimeZone) timezones.get(id); 1.147 - if (timezone == null) { 1.148 - timezone = (TimeZone) DEFAULT_TIMEZONES.get(id); 1.149 - if (timezone == null) { 1.150 - // if timezone not found with identifier, try loading an alias.. 1.151 - final String alias = ALIASES.getProperty(id); 1.152 - if (alias != null) { 1.153 - return getTimeZone(alias); 1.154 - } 1.155 - else { 1.156 - synchronized (DEFAULT_TIMEZONES) { 1.157 - // check again as it may be loaded now.. 1.158 - timezone = (TimeZone) DEFAULT_TIMEZONES.get(id); 1.159 - if (timezone == null) { 1.160 - try { 1.161 - final VTimeZone vTimeZone = loadVTimeZone(id); 1.162 - if (vTimeZone != null) { 1.163 - // XXX: temporary kludge.. 1.164 - // ((TzId) vTimeZone.getProperties().getProperty(Property.TZID)).setValue(id); 1.165 - timezone = new TimeZone(vTimeZone); 1.166 - DEFAULT_TIMEZONES.put(timezone.getID(), timezone); 1.167 - } 1.168 - else if (CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING)) { 1.169 - // strip global part of id and match on default tz.. 1.170 - Matcher matcher = TZ_ID_SUFFIX.matcher(id); 1.171 - if (matcher.find()) { 1.172 - return getTimeZone(matcher.group()); 1.173 - } 1.174 - } 1.175 - } 1.176 - catch (Exception e) { 1.177 - Log log = LogFactory.getLog(TimeZoneRegistryImpl.class); 1.178 - log.warn("Error occurred loading VTimeZone", e); 1.179 - } 1.180 - } 1.181 - } 1.182 - } 1.183 - } 1.184 - } 1.185 - return timezone; 1.186 - } 1.187 - 1.188 - /** 1.189 - * Loads an existing VTimeZone from the classpath corresponding to the specified Java timezone. 1.190 - */ 1.191 - private VTimeZone loadVTimeZone(final String id) throws IOException, ParserException { 1.192 - final URL resource = ResourceLoader.getResource(resourcePrefix + id + ".ics"); 1.193 - if (resource != null) { 1.194 - final CalendarBuilder builder = new CalendarBuilder(); 1.195 - final Calendar calendar = builder.build(resource.openStream()); 1.196 - final VTimeZone vTimeZone = (VTimeZone) calendar.getComponent(Component.VTIMEZONE); 1.197 - // load any available updates for the timezone.. can be explicility disabled via configuration 1.198 - if (!"false".equals(Configurator.getProperty(UPDATE_ENABLED))) { 1.199 - return updateDefinition(vTimeZone); 1.200 - } 1.201 - return vTimeZone; 1.202 - } 1.203 - return null; 1.204 - } 1.205 - 1.206 - /** 1.207 - * @param vTimeZone 1.208 - * @return 1.209 - */ 1.210 - private VTimeZone updateDefinition(VTimeZone vTimeZone) { 1.211 - final TzUrl tzUrl = vTimeZone.getTimeZoneUrl(); 1.212 - if (tzUrl != null) { 1.213 - try { 1.214 - final CalendarBuilder builder = new CalendarBuilder(); 1.215 - final Calendar calendar = builder.build(tzUrl.getUri().toURL().openStream()); 1.216 - final VTimeZone updatedVTimeZone = (VTimeZone) calendar.getComponent(Component.VTIMEZONE); 1.217 - if (updatedVTimeZone != null) { 1.218 - return updatedVTimeZone; 1.219 - } 1.220 - } 1.221 - catch (Exception e) { 1.222 - Log log = LogFactory.getLog(TimeZoneRegistryImpl.class); 1.223 - log.warn("Unable to retrieve updates for timezone: " + vTimeZone.getTimeZoneId().getValue(), e); 1.224 - } 1.225 - } 1.226 - return vTimeZone; 1.227 - } 1.228 -}