/** * VMware Continuent Tungsten Replicator * Copyright (C) 2015 VMware, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Initial developer(s): Robert Hodges * Contributor(s): */ package com.continuent.tungsten.common.config; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.Properties; import java.util.TreeMap; import com.continuent.tungsten.common.file.FileIO; import com.continuent.tungsten.common.file.FileIOException; import com.continuent.tungsten.common.file.FilePath; import com.continuent.tungsten.common.file.JavaFileIO; /** * This class reads and writes TungstenProperties data safely on a file system. * It uses the generic FileIO class to ensure that properties files are handled * as efficiently as possible. */ public class TungstenPropertiesIO { /** Process file using JSON format serialization. */ public static final String JSON = "JSON"; /** Process file using Java properties format serialization. */ public static final String JAVA_PROPERTIES = "JAVA_PROPERTIES"; // Properties with reasonable defaults. private String format = "JAVA_PROPERTIES"; private String charset = "UTF-8"; // Class to perform IO and location where to perform it. private final FileIO fileIO; private final FilePath filePath; /** * Creates a new instance with user-specified FileIO implementation and file * path. */ public TungstenPropertiesIO(FileIO fileIO, FilePath filePath) { this.fileIO = fileIO; this.filePath = filePath; } /** * Creates a new instance for OS file system operating on the * caller-specified file. */ public TungstenPropertiesIO(File path) { this(new JavaFileIO(), new FilePath(path.getAbsolutePath())); } public String getFormat() { return format; } /** Sets the serialization format to use. */ public void setFormat(String format) { this.format = format; } public String getCharset() { return charset; } /** Sets the character set to use. */ public void setCharset(String charset) { this.charset = charset; } /** Returns true if the properties file exists. */ public boolean exists() { return fileIO.exists(filePath); } /** * Delete the properties file. * * @return true if fully successful, otherwise false. */ public boolean delete() { return fileIO.delete(filePath, false); } /** * Write properties file to the file system using selected serialization * format and character set. * * @param properties Properties to be written * @param fsync If true issue an fsync, otherwise just flush * @throws FileIOException Thrown if file is not writable */ public void write(TungstenProperties properties, boolean fsync) throws FileIOException { String contents; if (JAVA_PROPERTIES.equals(format)) { // Output into sorted properties format. TreeMap<String, String> map = new TreeMap<String, String>( properties.map()); StringBuffer sb = new StringBuffer(); for (String key : map.keySet()) { sb.append(String.format("%s=%s\n", key, map.get(key))); } contents = sb.toString(); } else if (JSON.equals(format)) { try { contents = properties.toJSON(true); } catch (Exception e) { throw new FileIOException("Unable to convert to JSON: file=" + filePath.toString() + " format=" + format, e); } } else { throw new FileIOException( "Unrecognized property output format: file=" + filePath.toString() + " format=" + format); } // Write the results. fileIO.write(filePath, contents, charset, fsync); } /** * Read properties file from the file system using selected serialization * format and character set. * * @return Properties instance * @throws FileIOException Thrown if file is not readable */ public TungstenProperties read() throws FileIOException { // Read the file. String contents = fileIO.read(filePath, charset); // Deserialize using appropriate format. if (JAVA_PROPERTIES.equals(format)) { StringReader sr = new StringReader(contents); Properties javaProps = new Properties(); try { javaProps.load(sr); } catch (IOException e) { throw new FileIOException( "Unable to read JSON properties: file=" + filePath.toString() + " format=" + format, e); } sr.close(); TungstenProperties properties = new TungstenProperties(); properties.load(javaProps); return properties; } else if (JSON.equals(format)) { try { return TungstenProperties.loadFromJSON(contents); } catch (Exception e) { throw new FileIOException("Unable to convert to JSON: file=" + filePath.toString() + " format=" + format, e); } } else { throw new FileIOException( "Unrecognized property input format: file=" + filePath.toString() + " format=" + format); } } }