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

com.davfx.string.StringHandler Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.davfx.string;

import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public final class StringHandler {
	// Beware, with the current algorithm, this function cannot find '\'
	private static final int find(boolean skipBlocks, String s, char toFind, int from) {
		int open = 0;
		boolean escaping = false;
		for (int i = from; i < s.length(); i++) {
			if (escaping) {
				escaping = false;
				continue;
			}
			char c = s.charAt(i);
			if (c == '\\') {
				escaping = true;
				continue;
			}
			if ((open == 0) && (c == toFind)) {
				return i;
			} else if (skipBlocks && (c == '{')) {
				open++;
			} else if (skipBlocks && (c == '}')) {
				open--;
			}
		}
		return -1;
	}
	
	private final Map> factories = new HashMap<>();

	public StringHandler() {
		factories.put("null", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new NullStringInput();
			}
		});

		factories.put("before", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new BeforeStringInput(inputs[0], inputs[1]);
			}
		});

		factories.put("after", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new AfterStringInput(inputs[0], inputs[1]);
			}
		});

		factories.put("clean", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new CleanStringInput(inputs[0]);
			}
		});

		factories.put("ifnull", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				IfNullStringInput input = new IfNullStringInput();
				for (StringInput in : inputs) {
					input.add(in);
				}
				return input;
			}
		});

		factories.put("bitcompose", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new BitComposeStringInput(inputs[0], inputs[1], inputs[2]);
			}
		});

		factories.put("compositeprefix", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new CompositePrefixStringInput(inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], inputs[5]);
			}
		});
		factories.put("compositespecification", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new CompositeSpecificationStringInput(inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], inputs[5]);
			}
		});
		factories.put("compositevalue", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new CompositeValueStringInput(inputs[0], inputs[1], inputs[2], inputs[3], inputs[4], inputs[5], inputs[6]);
			}
		});
		
		factories.put("removeprefix", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new RemovePrefixStringInput(inputs[0], inputs[1]);
			}
		});
		factories.put("removesuffix", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new RemoveSuffixStringInput(inputs[0], inputs[1]);
			}
		});
		factories.put("getprefix", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new GetPrefixStringInput(inputs[0], inputs[1]);
			}
		});
		factories.put("getsuffix", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new GetSuffixStringInput(inputs[0], inputs[1]);
			}
		});

		factories.put("find", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new FindStringInput(inputs[0], inputs[1], inputs[2]);
			}
		});

		factories.put("replace", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new ReplaceStringInput(inputs[0], inputs[1], inputs[2]);
			}
		});

		factories.put("ifeq", new StringInputFactory() {
			@Override
			public StringInput build(StringInput[] inputs) {
				return new IfEqStringInput(inputs[0], inputs[1], inputs[2], inputs[2]);
			}
		});
	}
	
	public StringHandler add(String keyword, StringInputFactory factory) {
		factories.put(keyword, factory);
		return this;
	}
	
	private StringInput buildStringInput(String s) {
		int c = find(true, s, ':', 1); // 1 for '{'
		String keyword;
		String remaining;
		if (c < 0) {
			keyword = s.substring(1, s.length() - 1); // -1 for '}'
			remaining = null;
		} else {
			keyword = s.substring(1, c);
			remaining = s.substring(c + 1, s.length() - 1); // -1 for '}'
		}
		
		Deque> l = new LinkedList>();
		if (remaining != null) {
			int i = 0;
			while (true) {
				int d = find(true, remaining, ':', i);
				if (d < 0) {
					l.add(buildCompleteStringInput(remaining.substring(i)));
					break;
				}
				l.add(buildCompleteStringInput(remaining.substring(i, d)));
				i = d + 1;
			}
		}
		
		final StringInput keywordInput = buildCompleteStringInput(keyword);
		
		@SuppressWarnings("unchecked")
		final StringInput[] inputs = (StringInput[]) new StringInput[l.size()];
		l.toArray(inputs);

		return new StringInput() {
			@Override
			public String get(T h) {
				String kw = keywordInput.get(h);
				StringInputFactory factory = factories.get(kw);
				if (factory == null) {
					throw new RuntimeException("Invalid keyword: " + kw);
				}
				StringInput input = factory.build(inputs);
				if (input == null) {
					throw new RuntimeException("Invalid factory: " + kw);
				}
				return input.get(h);
			}
		};
	}
	
	private StringInput buildCompleteStringInput(String s) {
		AppendStringInput inputs = new AppendStringInput();
		int last = 0;
		while (true) {
			int a = find(false, s, '{', last);
			if (a < 0) {
				if (last < s.length()) {
					inputs.add(new EscapingStringInput(s.substring(last)));
				}
				break;
			}
			if (last < a) {
				inputs.add(new EscapingStringInput(s.substring(last, a)));
			}
			int b = find(true, s, '}', a + 1);
			inputs.add(buildStringInput(s.substring(a, b + 1)));
			last = b + 1;
		}
		return inputs;
	}
	
	public StringInput build(String configuration) {
		return buildCompleteStringInput(configuration);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy