001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.automation.core.util; 013 014import java.io.BufferedReader; 015import java.io.IOException; 016import java.io.Reader; 017import java.io.StringReader; 018import java.util.HashMap; 019import java.util.Iterator; 020import java.util.Map; 021import java.util.Map.Entry; 022 023import com.google.common.base.Objects; 024import org.codehaus.jackson.JsonNode; 025import org.codehaus.jackson.map.ObjectMapper; 026import org.nuxeo.ecm.automation.core.Constants; 027import org.nuxeo.runtime.api.Framework; 028 029/** 030 * Inline properties file content. This class exists to have a real type for parameters accepting properties content. 031 * 032 * @see Constants 033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 034 */ 035public class Properties extends HashMap<String, String> { 036 037 private static final long serialVersionUID = 1L; 038 039 public static final String PROPERTIES_MULTILINE_ESCAPE = "nuxeo" + ".automation.properties.multiline.escape"; 040 041 protected static final String multiLineEscape = Objects.firstNonNull( 042 Framework.getProperty(PROPERTIES_MULTILINE_ESCAPE), "true"); 043 044 public Properties() { 045 } 046 047 public Properties(int size) { 048 super(size); 049 } 050 051 public Properties(Map<String, String> props) { 052 super(props); 053 } 054 055 public Properties(String content) throws IOException { 056 StringReader reader = new StringReader(content); 057 loadProperties(reader, this); 058 } 059 060 /** 061 * Constructs a Properties map based on a Json node. 062 * 063 * @param node 064 * @throws IOException 065 * @since 5.7.3 066 */ 067 public Properties(JsonNode node) throws IOException { 068 Iterator<Entry<String, JsonNode>> fields = node.getFields(); 069 ObjectMapper om = new ObjectMapper(); 070 while (fields.hasNext()) { 071 Entry<String, JsonNode> entry = fields.next(); 072 String key = entry.getKey(); 073 JsonNode subNode = entry.getValue(); 074 put(key, extractValueFromNode(subNode, om)); 075 } 076 } 077 078 /** 079 * @param om 080 * @param subNode 081 * @return 082 * @throws IOException 083 * @since 5.8-HF01 084 */ 085 private String extractValueFromNode(JsonNode node, ObjectMapper om) throws IOException { 086 if (!node.isNull()) { 087 return node.isContainerNode() ? om.writeValueAsString(node) : node.getValueAsText(); 088 } else { 089 return null; 090 } 091 } 092 093 public static Map<String, String> loadProperties(Reader reader) throws IOException { 094 Map<String, String> map = new HashMap<String, String>(); 095 loadProperties(reader, map); 096 return map; 097 } 098 099 public static void loadProperties(Reader reader, Map<String, String> map) throws IOException { 100 BufferedReader in = new BufferedReader(reader); 101 String line = in.readLine(); 102 String prevLine = null; 103 while (line != null) { 104 line = line.trim(); 105 if (line.startsWith("#") || line.length() == 0) { 106 prevLine = null; 107 line = in.readLine(); 108 continue; 109 } 110 if (line.endsWith("\\") && Boolean.valueOf(multiLineEscape)) { 111 line = line.substring(0, line.length() - 1); 112 prevLine = prevLine != null ? prevLine + line : line; 113 line = in.readLine(); 114 continue; 115 } 116 if (prevLine != null) { 117 line = prevLine + "\n" + line; 118 } 119 prevLine = null; 120 setPropertyLine(map, line); 121 line = in.readLine(); 122 } 123 if (prevLine != null) { 124 setPropertyLine(map, prevLine); 125 } 126 } 127 128 protected static void setPropertyLine(Map<String, String> map, String line) throws IOException { 129 int i = line.indexOf('='); 130 if (i == -1) { 131 throw new IOException("Invalid property line: " + line); 132 } 133 map.put(line.substring(0, i).trim(), line.substring(i + 1).trim()); 134 } 135 136}