1 package org.daisy.pipeline.modules.impl;
2
3 import java.net.URI;
4 import java.nio.file.NoSuchFileException;
5 import java.util.LinkedList;
6
7 import org.daisy.pipeline.modules.Component;
8 import org.daisy.pipeline.modules.Module;
9 import org.daisy.pipeline.modules.ResolutionException;
10 import org.daisy.pipeline.xmlcatalog.XmlCatalogParser;
11 import org.osgi.service.component.annotations.Activate;
12 import org.osgi.service.component.annotations.Reference;
13 import org.osgi.service.component.annotations.ReferenceCardinality;
14 import org.osgi.service.component.annotations.ReferencePolicy;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.slf4j.helpers.NOPLogger;
18
19 @org.osgi.service.component.annotations.Component(
20 name = "org.daisy.pipeline.modules.impl.Module_common_utils",
21 service = { Module.class }
22 )
23 public class Module_common_utils extends Module {
24
25 private static final Logger logger = LoggerFactory.getLogger(Module_common_utils.class);
26
27 private boolean initialized = false;
28 private XmlCatalogParser catalogParser;
29 private final LinkedList<Component> componentsToAdd;
30 private final LinkedList<Component> componentsBeingAdded;
31
32 public Module_common_utils() {
33 super("common-utils",
34 "3.1.3",
35 "DAISY Pipeline 2 module :: Common Utilities");
36 componentsToAdd = new LinkedList<>();
37 componentsBeingAdded = new LinkedList<>();
38 }
39
40 @Reference(
41 name = "XmlCatalogParser",
42 unbind = "-",
43 service = XmlCatalogParser.class,
44 cardinality = ReferenceCardinality.MANDATORY,
45 policy = ReferencePolicy.STATIC
46 )
47 public void setParser(XmlCatalogParser parser) {
48 catalogParser = parser;
49 }
50
51 @Activate
52 protected void init() {
53 logger.debug("Initializing module " + getName());
54 Module tmpModule = new Module(getName(), getVersion(), getTitle()) {
55 @Override public void resolveDependencies() {}
56 @Override public Logger getLogger() { return NOPLogger.NOP_LOGGER; }
57 };
58 Module.parseCatalog(tmpModule, catalogParser);
59 for (String e : tmpModule.getEntities()) {
60 addEntity(tmpModule.getEntity(e));
61 logger.debug("Loaded entity: " + e);
62 }
63 for (URI c : tmpModule.getComponents()) {
64 components.put(c, () -> null);
65 componentsToAdd.add(tmpModule.getComponent(c));
66 }
67 logger.debug("Module " + getName() + " initialized, but dependencies have not been resolved yet");
68 }
69
70
71
72
73
74
75 @Override
76 public void resolveDependencies() {
77 if (!initialized) {
78 boolean recursive = !componentsBeingAdded.isEmpty();
79 if (recursive)
80 logger.debug("Resolving dependencies of module " + getName() + " (continuing in recursive call)");
81 else
82 logger.debug("Resolving dependencies of module " + getName());
83 while (true) {
84 if (componentsToAdd.isEmpty()) {
85 if (componentsBeingAdded.isEmpty())
86 break;
87 componentsToAdd.addAll(componentsBeingAdded);
88 componentsBeingAdded.clear();
89 }
90 Component c = componentsToAdd.poll();
91 componentsBeingAdded.add(c);
92 if (addComponent(c))
93 logger.debug("Loaded component: " + c.getURI());
94 componentsBeingAdded.remove(c);
95 componentsToAdd.remove(c);
96 }
97 if (!initialized)
98 logger.debug("Done resolving dependencies of module " + getName());
99 initialized = true;
100 }
101 }
102
103 @Override
104 protected boolean addComponent(Component component) {
105 String name = component.getURI().toString();
106 try {
107 if ("http://www.daisy.org/pipeline/modules/common-utils/i18n.xsl".equals(name)) {
108 tryResolveXPathExtensionFunction("org.daisy.pipeline.common.NormalizeLang");
109 }
110 } catch (ResolutionException re) {
111 logger.warn("Component " + component.getURI() + " can not be loaded: " + re.getMessage());
112 return false;
113 }
114 return super.addComponent(component);
115 }
116
117 private void tryResolveXPathExtensionFunction(String className) throws ResolutionException {
118 try {
119 getResource("../" + className.replace('.', '/') + ".class");
120 return;
121 } catch (NoSuchFileException e) {
122 }
123
124 try {
125 Class.forName(className);
126 return;
127 } catch (Throwable e) {
128 }
129 throw new ResolutionException(
130 "Unresolved Java dependency: no class " + className + " found on the class path");
131 }
132 }