package aQute.bnd.make;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Instruction;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.Resource;
import aQute.bnd.service.MakePlugin;
public class Make {
private final static Logger logger = LoggerFactory.getLogger(Make.class);
Builder builder;
Map<Instruction,Map<String,String>> make;
public Make(Builder builder) {
this.builder = builder;
}
public Resource process(String source) {
Map<Instruction,Map<String,String>> make = getMakeHeader();
logger.debug("make {}", source);
for (Map.Entry<Instruction,Map<String,String>> entry : make.entrySet()) {
Instruction instr = entry.getKey();
Matcher m = instr.getMatcher(source);
if (m.matches() || instr.isNegated()) {
Map<String,String> arguments = replace(m, entry.getValue());
List<MakePlugin> plugins = builder.getPlugins(MakePlugin.class);
for (MakePlugin plugin : plugins) {
try {
Resource resource = plugin.make(builder, source, arguments);
if (resource != null) {
logger.debug("Made {} from args {} with {}", source, arguments, plugin);
return resource;
}
} catch (Exception e) {
builder.exception(e, "Plugin %s generates error when use in making %s with args %s", plugin,
source, arguments);
}
}
}
}
return null;
}
private Map<String,String> replace(Matcher m, Map<String,String> value) {
Map<String,String> newArgs = Processor.newMap();
for (Map.Entry<String,String> entry : value.entrySet()) {
String s = entry.getValue();
s = replace(m, s);
newArgs.put(entry.getKey(), s);
}
return newArgs;
}
String replace(Matcher m, CharSequence s) {
StringBuilder sb = new StringBuilder();
int max = '0' + m.groupCount() + 1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '$' && i < s.length() - 1) {
c = s.charAt(++i);
if (c >= '0' && c <= max) {
int index = c - '0';
String replacement = m.group(index);
if (replacement != null)
sb.append(replacement);
} else {
if (c == '$')
i++;
sb.append(c);
}
} else
sb.append(c);
}
return sb.toString();
}
Map<Instruction,Map<String,String>> getMakeHeader() {
if (make != null)
return make;
make = Processor.newMap();
Parameters make = builder.getMergedParameters(Builder.MAKE);
for (Entry<String,Attrs> entry : make.entrySet()) {
String pattern = Processor.removeDuplicateMarker(entry.getKey());
Instruction instr = new Instruction(pattern);
this.make.put(instr, entry.getValue());
}
return this.make;
}
}