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 */ 019package org.apache.reef.tang.implementation; 020 021import org.apache.reef.tang.*; 022import org.apache.reef.tang.exceptions.BindException; 023import org.apache.reef.tang.implementation.java.ClassHierarchyImpl; 024import org.apache.reef.tang.implementation.java.InjectorImpl; 025import org.apache.reef.tang.implementation.java.JavaConfigurationBuilderImpl; 026 027import java.net.URL; 028import java.util.*; 029 030public class TangImpl implements Tang { 031 032 private static Map<SetValuedKey, JavaClassHierarchy> defaultClassHierarchy = new HashMap<>(); 033 034 /** 035 * Only for testing. Deletes Tang's current database of known classes, forcing 036 * it to rebuild them over time. 037 */ 038 public static void reset() { 039 defaultClassHierarchy = new HashMap<>(); 040 } 041 042 @Override 043 public Injector newInjector(final Configuration... confs) throws BindException { 044 return new InjectorImpl(new JavaConfigurationBuilderImpl(confs).build()); 045 } 046 047 @SuppressWarnings("unchecked") 048 @Override 049 public JavaConfigurationBuilder newConfigurationBuilder() { 050 try { 051 return newConfigurationBuilder(new URL[0], new Configuration[0], new Class[0]); 052 } catch (final BindException e) { 053 throw new IllegalStateException( 054 "Caught unexpected bind exception! Implementation bug.", e); 055 } 056 } 057 058 @Override 059 public ConfigurationBuilder newConfigurationBuilder(final ClassHierarchy ch) { 060 return new ConfigurationBuilderImpl(ch); 061 } 062 063 @SuppressWarnings("unchecked") 064 @Override 065 public JavaConfigurationBuilder newConfigurationBuilder(final URL... jars) { 066 try { 067 return newConfigurationBuilder(jars, new Configuration[0], new Class[0]); 068 } catch (final BindException e) { 069 throw new IllegalStateException( 070 "Caught unexpected bind exception! Implementation bug.", e); 071 } 072 } 073 074 @SuppressWarnings("unchecked") 075 @Override 076 public JavaConfigurationBuilder newConfigurationBuilder( 077 final Configuration... confs) throws BindException { 078 return newConfigurationBuilder(new URL[0], confs, new Class[0]); 079 } 080 081 @Override 082 public final JavaConfigurationBuilder newConfigurationBuilder( 083 @SuppressWarnings("unchecked") final Class<? extends ExternalConstructor<?>>... parsers) throws BindException { 084 return newConfigurationBuilder(new URL[0], new Configuration[0], parsers); 085 } 086 087 @Override 088 public JavaConfigurationBuilder newConfigurationBuilder(final URL[] jars, final Configuration[] confs, 089 final Class<? extends ExternalConstructor<?>>[] parameterParsers) 090 throws BindException { 091 return new JavaConfigurationBuilderImpl(jars, confs, parameterParsers); 092 } 093 094 @SuppressWarnings("unchecked") 095 @Override 096 public JavaClassHierarchy getDefaultClassHierarchy() { 097 return getDefaultClassHierarchy(new URL[0], new Class[0]); 098 } 099 100 @Override 101 public JavaClassHierarchy getDefaultClassHierarchy(final URL[] jars, 102 final Class<? extends ExternalConstructor<?>>[] parameterParsers) { 103 final SetValuedKey key = new SetValuedKey(jars, parameterParsers); 104 105 JavaClassHierarchy ret = defaultClassHierarchy.get(key); 106 if (ret == null) { 107 ret = new ClassHierarchyImpl(jars, parameterParsers); 108 defaultClassHierarchy.put(key, ret); 109 } 110 return ret; 111 } 112 113 @Override 114 public Injector newInjector(final Configuration confs) { 115 try { 116 return newInjector(new Configuration[]{confs}); 117 } catch (final BindException e) { 118 throw new IllegalStateException("Unexpected error cloning configuration", e); 119 } 120 } 121 122 @Override 123 public Injector newInjector() { 124 try { 125 return newInjector(new Configuration[]{}); 126 } catch (final BindException e) { 127 throw new IllegalStateException("Unexpected error from empty configuration", e); 128 } 129 } 130 131 private class SetValuedKey { 132 private final Set<Object> key; 133 134 SetValuedKey(final Object[] ts, final Object[] us) { 135 key = new HashSet<>(Arrays.asList(ts)); 136 key.addAll(Arrays.asList(us)); 137 } 138 139 @Override 140 public int hashCode() { 141 int i = 0; 142 for (final Object t : key) { 143 i += t.hashCode(); 144 } 145 return i; 146 } 147 148 @Override 149 public boolean equals(final Object o) { 150 if (this == o) { 151 return true; 152 } 153 if (o == null || getClass() != o.getClass()) { 154 return false; 155 } 156 final SetValuedKey other = (SetValuedKey) o; 157 if (other.key.size() != this.key.size()) { 158 return false; 159 } 160 return key.containsAll(other.key); 161 } 162 } 163 164 165}