001package org.nasdanika.html.model.app.graph.emf; 002 003import java.util.Collection; 004 005import org.eclipse.emf.common.util.URI; 006import org.eclipse.emf.ecore.EOperation; 007import org.eclipse.emf.ecore.EReference; 008import org.nasdanika.common.ProgressMonitor; 009import org.nasdanika.common.Supplier; 010import org.nasdanika.graph.emf.EOperationConnection; 011import org.nasdanika.graph.emf.EReferenceConnection; 012import org.nasdanika.graph.emf.QualifiedConnection; 013import org.nasdanika.graph.processor.ConnectionProcessorConfig; 014import org.nasdanika.html.model.app.Label; 015import org.nasdanika.html.model.app.Link; 016import org.nasdanika.html.model.app.graph.WidgetFactory; 017 018public class ConnectionProcessor { 019 020 protected URI sourceURI; 021 protected URI targetURI; 022 protected ConnectionProcessorConfig<WidgetFactory, WidgetFactory> config; 023 024 public ConnectionProcessor(ConnectionProcessorConfig<WidgetFactory, WidgetFactory> config) { 025 this.config = config; 026 027 config.getSourceEndpoint().thenAccept(se -> config.setTargetHandler(createTargetHandler(se))); 028 config.getTargetEndpoint().thenAccept(te -> config.setSourceHandler(createSourceHandler(te))); 029 } 030 031 protected WidgetFactory createTargetHandler(WidgetFactory sourceEndpoint) { 032 return new WidgetFactory() { 033 034 @Override 035 public void resolve(URI base, ProgressMonitor progressMonitor) { 036 targetURI = base; 037 } 038 039 private URI resolveBase(URI base) { 040 if (base == null) { 041 return targetURI; 042 } 043 if (base.isRelative() && targetURI != null && !targetURI.isRelative()) { 044 return base.resolve(targetURI); 045 } 046 return base; 047 } 048 049 @SuppressWarnings("unchecked") 050 @Override 051 public String createWidgetString(Object selector, URI base, ProgressMonitor progressMonitor) { 052 if (selector instanceof Selector) { 053 return createWidget((Selector<String>) selector, base, progressMonitor); 054 } 055 return sourceEndpoint.createWidgetString(selector, resolveBase(base), progressMonitor); 056 } 057 058 @Override 059 public Object createWidget(Object selector, URI base, ProgressMonitor progressMonitor) { 060 if (selector instanceof Selector) { 061 return createWidget((Selector<?>) selector, base, progressMonitor); 062 } 063 return sourceEndpoint.createWidget(selector, resolveBase(base), progressMonitor); 064 } 065 066 @Override 067 public <T> T createWidget(Selector<T> selector, URI base, ProgressMonitor progressMonitor) { 068 if (selector instanceof ConnectionSelector) { 069 return selector.createWidget(this, resolveBase(base), progressMonitor); 070 } 071 return sourceEndpoint.createWidget(selector, resolveBase(base), progressMonitor); 072 } 073 074 @Override 075 public String createLinkString(URI base, ProgressMonitor progressMonitor) { 076 return sourceEndpoint.createLinkString(resolveBase(base), progressMonitor); 077 } 078 079 @Override 080 public Object createLink(URI base, ProgressMonitor progressMonitor) { 081 return sourceEndpoint.createLink(resolveBase(base), progressMonitor); 082 } 083 084 @Override 085 public Label createHelpDecorator(URI base, ProgressMonitor progressMonitor) { 086 return sourceEndpoint.createHelpDecorator(resolveBase(base), progressMonitor); 087 } 088 089 @Override 090 public Supplier<Collection<Label>> createLabelsSupplier() { 091 return sourceEndpoint.createLabelsSupplier().then(labels -> { 092 for (Label label : labels) { 093 if (label instanceof Link) { 094 ((Link) label).rebase(targetURI, sourceURI); 095 } 096 } 097 return labels; 098 }); 099 } 100 101 @Override 102 public String createLabelString(ProgressMonitor progressMonitor) { 103 return sourceEndpoint.createLabelString(progressMonitor); 104 } 105 106 @Override 107 public Object createLabel(ProgressMonitor progressMonitor) { 108 return sourceEndpoint.createLabel(progressMonitor); 109 } 110 111 }; 112 113 } 114 115 protected WidgetFactory createSourceHandler(WidgetFactory targetEndpoint) { 116 return new WidgetFactory() { 117 118 @Override 119 public void resolve(URI base, ProgressMonitor progressMonitor) { 120 sourceURI = base; 121 QualifiedConnection<?> conn = (QualifiedConnection<?>) config.getElement(); 122 String path = conn.getPath(); 123 if (conn instanceof EReferenceConnection) { 124 EReference eRef = ((EReferenceConnection) conn).getReference(); 125 if (eRef.isContainment()) { 126 String uriStr = "references/" + eRef.getName() + "/"; 127 if (path != null) { 128 uriStr += path + "/"; 129 } 130 URI refURI = URI.createURI(uriStr); 131 targetEndpoint.resolve(refURI.resolve(base), progressMonitor); 132 } 133 } else if (conn instanceof EOperationConnection) { 134 EOperation eOp = ((EOperationConnection) conn).getOperation(); 135 String uriStr = "operations/" + eOp.getName() + "/"; 136 if (path != null) { 137 uriStr += path + "/"; 138 } 139 URI refURI = URI.createURI(uriStr); 140 targetEndpoint.resolve(refURI.resolve(base), progressMonitor); 141 } 142 } 143 144 private URI resolveBase(URI base) { 145 if (base == null) { 146 return sourceURI; 147 } 148 if (base.isRelative() && sourceURI != null && !sourceURI.isRelative()) { 149 return base.resolve(sourceURI); 150 } 151 return base; 152 } 153 154 @SuppressWarnings("unchecked") 155 @Override 156 public String createWidgetString(Object selector, URI base, ProgressMonitor progressMonitor) { 157 if (selector instanceof Selector) { 158 return createWidget((Selector<String>) selector, base, progressMonitor); 159 } 160 return targetEndpoint.createWidgetString(selector, resolveBase(base), progressMonitor); 161 } 162 163 @Override 164 public Object createWidget(Object selector, URI base, ProgressMonitor progressMonitor) { 165 if (selector instanceof Selector) { 166 return createWidget((Selector<?>) selector, base, progressMonitor); 167 } 168 return targetEndpoint.createWidget(selector, resolveBase(base), progressMonitor); 169 } 170 171 @Override 172 public <T> T createWidget(Selector<T> selector, URI base, ProgressMonitor progressMonitor) { 173 if (selector instanceof ConnectionSelector) { 174 return selector.createWidget(this, resolveBase(base), progressMonitor); 175 } 176 return targetEndpoint.createWidget(selector, resolveBase(base), progressMonitor); 177 } 178 179 @Override 180 public String createLinkString(URI base, ProgressMonitor progressMonitor) { 181 return targetEndpoint.createLinkString(resolveBase(base), progressMonitor); 182 } 183 184 @Override 185 public Object createLink(URI base, ProgressMonitor progressMonitor) { 186 return targetEndpoint.createLink(resolveBase(base), progressMonitor); 187 } 188 189 @Override 190 public Label createHelpDecorator(URI base, ProgressMonitor progressMonitor) { 191 return targetEndpoint.createHelpDecorator(resolveBase(base), progressMonitor); 192 } 193 194 @Override 195 public Supplier<Collection<Label>> createLabelsSupplier() { 196 return targetEndpoint.createLabelsSupplier().then(labels -> { 197 for (Label label : labels) { 198 if (label instanceof Link) { 199 ((Link) label).rebase(targetURI, sourceURI); 200 } 201 } 202 return labels; 203 }); 204 } 205 206 @Override 207 public String createLabelString(ProgressMonitor progressMonitor) { 208 return targetEndpoint.createLabelString(progressMonitor); 209 } 210 211 @Override 212 public Object createLabel(ProgressMonitor progressMonitor) { 213 return targetEndpoint.createLabel(progressMonitor); 214 } 215 216 }; 217 } 218 219}