package org.infinispan.scripting.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.infinispan.scripting.logging.Log; import org.infinispan.util.logging.LogFactory; public class ScriptMetadataParser { private static final Log log = LogFactory.getLog(ScriptMetadataParser.class, Log.class); private static final String DEFAULT_SCRIPT_EXTENSION = "js"; private static final Pattern METADATA_COMMENT = Pattern.compile("^(?:#|//|;;)\\s*(.+)"); private static final Pattern METADATA_KV = Pattern .compile("\\s*(\\w+)\\s*=\\s*(\"[^\"]*\"|\'[^\']*\'|\\[[\\w,\\s]*\\]|[^,=\\s\"]+)\\s*,?"); public static ScriptMetadata parse(String name, String script) { ScriptMetadata.Builder metadataBuilder = new ScriptMetadata.Builder(); metadataBuilder.name(name); metadataBuilder.mode(ExecutionMode.LOCAL); int s = name.lastIndexOf(".") + 1; if (s == 0 || s == name.length()) metadataBuilder.extension(DEFAULT_SCRIPT_EXTENSION); else metadataBuilder.extension(name.substring(s)); try (BufferedReader r = new BufferedReader(new StringReader(script))) { for (String line = r.readLine(); line != null; line = r.readLine()) { Matcher matcher = METADATA_COMMENT.matcher(line); if (!matcher.matches()) break; String text = matcher.group(1); matcher = METADATA_KV.matcher(text); while (matcher.find()) { String key = matcher.group(1).toLowerCase(); String value = unquote(matcher.group(2)); switch (key) { case "name": metadataBuilder.name(value); break; case "extension": metadataBuilder.extension(value); break; case "language": metadataBuilder.language(value); break; case "mode": metadataBuilder.mode(ExecutionMode.valueOf(value.toUpperCase())); break; case "parameters": metadataBuilder.parameters(unarray(value)); break; case "role": metadataBuilder.role(value); break; case "reducer": metadataBuilder.reducer(value); break; case "combiner": metadataBuilder.combiner(value); break; case "collator": metadataBuilder.collator(value); break; case "datatype": metadataBuilder.dataType(DataType.fromMime(value)); break; default: throw log.unknownScriptProperty(key); } } } } catch (IOException e) { } return metadataBuilder.build(); } private static String unquote(String s) { if (s.charAt(0) == '"' || s.charAt(0) == '\'') { return s.substring(1, s.length() - 1); } else { return s; } } private static Set<String> unarray(String s) { if (s.charAt(0) == '[') { String[] ps = s.substring(1, s.length() - 1).split("\\s*,\\s*"); Set<String> parameters = new HashSet<>(); for (String p : ps) { parameters.add(p); } return parameters; } else { throw log.parametersNotArray(); } } }