This project has retired. For details please refer to its Attic page.
Source code
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.formats;
020
021import org.apache.commons.configuration.ConfigurationException;
022import org.apache.commons.configuration.PropertiesConfiguration;
023import org.apache.reef.tang.Configuration;
024import org.apache.reef.tang.ConfigurationBuilder;
025import org.apache.reef.tang.exceptions.BindException;
026import org.apache.reef.tang.exceptions.ClassHierarchyException;
027import org.apache.reef.tang.implementation.ConfigurationBuilderImpl;
028import org.apache.reef.tang.implementation.ConfigurationImpl;
029import org.apache.reef.tang.types.ClassNode;
030import org.apache.reef.tang.types.ConstructorArg;
031import org.apache.reef.tang.types.NamedParameterNode;
032import org.apache.reef.tang.types.Node;
033import org.apache.reef.tang.util.ReflectionUtilities;
034
035import java.io.File;
036import java.io.FileOutputStream;
037import java.io.IOException;
038import java.io.PrintStream;
039import java.util.*;
040import java.util.Map.Entry;
041
042/**
043 * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
044 */
045@Deprecated
046public class ConfigurationFile {
047
048  /**
049   * Write Configuration to the given File.
050   *
051   * @throws IOException
052   * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
053   */
054  @Deprecated
055  public static void writeConfigurationFile(
056      final Configuration conf, final File confFile) throws IOException {
057    try (final PrintStream printStream = new PrintStream(new FileOutputStream(confFile))) {
058      printStream.print(toConfigurationString(conf));
059    }
060  }
061
062  /**
063   * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
064   */
065  @Deprecated
066  public static void addConfiguration(final ConfigurationBuilder conf,
067                                      final File tmpConfFile) throws IOException, BindException {
068    final PropertiesConfiguration confFile;
069    try {
070      confFile = new PropertiesConfiguration(tmpConfFile);
071    } catch (final ConfigurationException e) {
072      throw new BindException("Problem parsing config file: " + tmpConfFile, e);
073    }
074    processConfigFile(conf, confFile);
075  }
076
077  /**
078   * @param conf     This configuration builder will be modified to incorporate the
079   *                 contents of the configuration file.
080   * @param contents A string containing the contents of the configuration file.
081   * @throws BindException
082   * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
083   */
084  @Deprecated
085  public static void addConfiguration(final ConfigurationBuilder conf,
086                                      final String contents) throws BindException {
087    File tmpConfFile = null;
088    try {
089      tmpConfFile = File.createTempFile("tang", "tmp");
090      try (final FileOutputStream outStream = new FileOutputStream(tmpConfFile)) {
091        outStream.write(contents.getBytes());
092      }
093      addConfiguration(conf, tmpConfFile);
094    } catch (final IOException ex) {
095      throw new BindException("Error writing config file: " + tmpConfFile, ex);
096    } finally {
097      if (tmpConfFile != null) {
098        tmpConfFile.delete();
099      }
100    }
101  }
102
103  private static void processConfigFile(ConfigurationBuilder conf,
104                                        PropertiesConfiguration confFile) throws IOException, BindException {
105    ConfigurationBuilderImpl ci = (ConfigurationBuilderImpl) conf;
106    Iterator<String> it = confFile.getKeys();
107    Map<String, String> importedNames = new HashMap<>();
108
109    while (it.hasNext()) {
110      String key = it.next();
111      String longName = importedNames.get(key);
112      String[] values = confFile.getStringArray(key);
113      if (longName != null) {
114        // System.err.println("Mapped " + key + " to " + longName);
115        key = longName;
116      }
117      for (String value : values) {
118        try {
119          if (key.equals(ConfigurationBuilderImpl.IMPORT)) {
120            ci.getClassHierarchy().getNode(value);
121            final String[] tok = value.split(ReflectionUtilities.regexp);
122            final String lastTok = tok[tok.length - 1];
123            try {
124              // ci.namespace.getNode(lastTok);
125              ci.getClassHierarchy().getNode(lastTok);
126              throw new IllegalArgumentException("Conflict on short name: " + lastTok);
127            } catch (BindException e) {
128              String oldValue = importedNames.put(lastTok, value);
129              if (oldValue != null) {
130                throw new IllegalArgumentException("Name conflict: "
131                    + lastTok + " maps to " + oldValue + " and " + value);
132              }
133            }
134          } else if (value.startsWith(ConfigurationBuilderImpl.INIT)) {
135            String parseValue = value.substring(
136                ConfigurationBuilderImpl.INIT.length(), value.length());
137            parseValue = parseValue.replaceAll("^[\\s\\(]+", "");
138            parseValue = parseValue.replaceAll("[\\s\\)]+$", "");
139            String[] classes = parseValue.split("[\\s\\-]+");
140            ci.registerLegacyConstructor(key, classes);
141          } else {
142            ci.bind(key, value);
143          }
144        } catch (BindException e) {
145          throw new BindException("Failed to process configuration tuple: [" + key + "=" + value + "]", e);
146        } catch (ClassHierarchyException e) {
147          throw new ClassHierarchyException("Failed to process configuration tuple: [" + key + "=" + value + "]", e);
148        }
149      }
150    }
151  }
152
153  /**
154   * Replace any \'s in the input string with \\. and any "'s with \".
155   *
156   * @param in
157   * @return
158   */
159  private static String escape(String in) {
160    // After regexp escaping \\\\ = 1 slash, \\\\\\\\ = 2 slashes.
161
162    // Also, the second args of replaceAll are neither strings nor regexps, and
163    // are instead a special DSL used by Matcher. Therefore, we need to double
164    // escape slashes (4 slashes) and quotes (3 slashes + ") in those strings.
165    // Since we need to write \\ and \", we end up with 8 and 7 slashes,
166    // respectively.
167    return in.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\\\"");
168  }
169
170  /**
171   * Obtain the effective configuration of this ConfigurationBuilderImpl
172   * instance. This consists of string-string pairs that could be written
173   * directly to a Properties file, for example. Currently, this method does not
174   * return information about default parameter values that were specified by
175   * parameter annotations, or about the auto-discovered stuff in TypeHierarchy.
176   * All of that should be automatically imported as these keys are parsed on
177   * the other end.
178   *
179   * @return A string containing enough information to rebuild this
180   * configuration object (assuming the same classes / jars are
181   * available when the string is parsed by Tang).
182   * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
183   */
184  @Deprecated
185  public static String toConfigurationString(final Configuration c) {
186    StringBuilder sb = new StringBuilder();
187    for (String s : toConfigurationStringList(c)) {
188      sb.append(s);
189      sb.append('\n');
190    }
191    return sb.toString();
192  }
193
194  /**
195   * @deprecated in Tang 0.2 Use AvroConfigurationSerializer instead.
196   */
197  @Deprecated
198  static List<String> toConfigurationStringList(final Configuration c) {
199    ConfigurationImpl conf = (ConfigurationImpl) c;
200    List<String> l = new ArrayList<>();
201    for (ClassNode<?> opt : conf.getBoundImplementations()) {
202      l.add(opt.getFullName()
203          + '='
204          + escape(conf.getBoundImplementation(opt).getFullName()));
205    }
206    for (ClassNode<?> opt : conf.getBoundConstructors()) {
207      l.add(opt.getFullName()
208          + '='
209          + escape(conf.getBoundConstructor(opt).getFullName()));
210    }
211    for (NamedParameterNode<?> opt : conf.getNamedParameters()) {
212      l.add(opt.getFullName()
213          + '='
214          + escape(conf.getNamedParameter(opt)));
215    }
216    for (ClassNode<?> cn : conf.getLegacyConstructors()) {
217      StringBuilder sb = new StringBuilder();
218      join(sb, "-", conf.getLegacyConstructor(cn).getArgs());
219      l.add(cn.getFullName()
220          + escape('='
221              + ConfigurationBuilderImpl.INIT
222              + '('
223              + sb.toString()
224              + ')'
225      ));
226      //s.append(cn.getFullName()).append('=').append(ConfigurationBuilderImpl.INIT).append('(');
227//      .append(")\n");
228    }
229    for (Entry<NamedParameterNode<Set<?>>, Object> e : conf.getBoundSets()) {
230      final String val;
231      if (e.getValue() instanceof String) {
232        val = (String) e.getValue();
233      } else if (e.getValue() instanceof Node) {
234        val = ((Node) e.getValue()).getFullName();
235      } else {
236        throw new IllegalStateException();
237      }
238      l.add(e.getKey().getFullName() + '=' + escape(val));
239//      s.append(e.getKey().getFullName()).append('=').append(val).append("\n");
240    }
241    return l;//s.toString();
242  }
243
244  private static StringBuilder join(final StringBuilder sb, final String sep, final ConstructorArg[] types) {
245    if (types.length > 0) {
246      sb.append(types[0].getType());
247      for (int i = 1; i < types.length; i++) {
248        sb.append(sep).append(types[i].getType());
249      }
250    }
251    return sb;
252  }
253}