All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.libg.parameters.ParameterMap Maven / Gradle / Ivy

There is a newer version: 7.0.0
Show newest version
package aQute.libg.parameters;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import aQute.libg.glob.Glob;
import aQute.libg.qtokens.QuotedTokenizer;

public class ParameterMap extends LinkedHashMap {
	private static final char	DUPLICATE_MARKER	= '~';
	private static final long	serialVersionUID	= 1L;

	public ParameterMap() {}

	/**
	 * 
	 * parameters ::= clause ( ',' clause ) *
	 * clause ::=  key ( ';' key )* ( '=' value ) ( ';' key '=' value )*
	 * key    ::= NAME ( ':' type )
	 * type   ::= List, ...
	 * 
* * @param parameters */ public ParameterMap(String parameters) { this(); if (parameters != null) { new Parser(parameters).parse(); } } public ParameterMap(Map> maps) { this(); maps.forEach((k, v) -> put(k, new Attributes(v))); } class Parser { private final String parameters; private final QuotedTokenizer qt; private final Map duplicates = new HashMap<>(); Parser(String parameters) { this.parameters = parameters; qt = new QuotedTokenizer(parameters, ";=,", false); } void parse() { do { // parameters ::= clause ( ',' clause ) * clause(); } while (qt.getSeparator() == ','); String token = qt.nextToken(); error(token != null && !token.isEmpty(), "Parsing header: '" + parameters + "' has trailing " + qt); } /* * clause = key ( ';' keyOrAttribute )* ( '=' attributeValue ) * attributes * */ private void clause() { Attributes attrs = new Attributes(); // key String key = qt.nextToken(";,"); if (key == null) return; put(uniqueKey(key), attrs); while (qt.getSeparator() == ';') { String keyOrAttribute = qt.nextToken(";=,"); error(keyOrAttribute == null, "expected a clause key or attribute key"); switch (qt.getSeparator()) { case '=' : String attributeValue = qt.nextToken(";,"); error(attributeValue == null, "expected an attribute value"); attrs.put(keyOrAttribute, attributeValue); attributes(attrs); break; case ';' : case ',' : put(uniqueKey(keyOrAttribute), attrs); break; default : error(true, "unrecognized separator "); } } } private String uniqueKey(String key) { return duplicates.compute(key, (k, v) -> ParameterMap.this.uniqueKey((v == null) ? k : v + DUPLICATE_MARKER)); } // attributes = attribute * private void attributes(Map attrs) { while (qt.getSeparator() == ';') { attribute(attrs); } } private void attribute(Map attrs) { String attributeKey = qt.nextToken("=,;"); error(attributeKey == null, "expected an attribute key"); error(qt.getSeparator() != '=', "expected an equal sign after an attribute key"); String attributeValue = qt.nextToken(";,"); error(attributeValue == null, "expected an attribute value"); attrs.put(attributeKey, attributeValue); } private void error(boolean b, String string) { if (b) throw new IllegalArgumentException(string + " : " + qt); } } public Map put(String key, Map attrs) { key = uniqueKey(key); return super.put(key, (attrs == null) ? new Attributes() : new Attributes(attrs)); } @Override public String toString() { StringBuilder sb = new StringBuilder(); append(sb); return sb.toString(); } private void append(StringBuilder appendable) { String del = ""; for (Map.Entry e : entrySet()) { String key = e.getKey(); key = removeDuplicateMarker(key); appendable.append(del); appendable.append(key); e.getValue() .append(appendable); del = ","; } } public static boolean isDuplicate(String key) { return key.indexOf(DUPLICATE_MARKER, key.length() - 1) >= 0; } String uniqueKey(String key) { while (containsKey(key)) { key += DUPLICATE_MARKER; } return key; } public static String removeDuplicateMarker(String key) { int i = key.length() - 1; while ((i >= 0) && (key.charAt(i) == DUPLICATE_MARKER)) { --i; } return key.substring(0, i + 1); } public ParameterMap restrict(Collection matchers) { ParameterMap result = new ParameterMap(); Set negated = new HashSet<>(); List sequence = new ArrayList<>(); for (String s : matchers) { Glob g; if (s.startsWith("!")) { g = new Glob(s.substring(1)); negated.add(g); } else { g = new Glob(s); } sequence.add(g); } nextEntry: for (java.util.Map.Entry e : this.entrySet()) { for (Glob g : sequence) { if (g.matches(e.getKey())) { if (!negated.contains(g)) result.put(e.getKey(), e.getValue()); continue nextEntry; } } } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy