import java.io.IOException;
import java.math.BigInteger;
+import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import org.simantics.acorn.lru.ClusterStreamChunk;
import org.simantics.acorn.lru.FileInfo;
import org.simantics.acorn.lru.LRU;
+import org.simantics.databoard.file.RuntimeIOException;
import org.simantics.db.ClusterCreator;
import org.simantics.db.Database.Session.ClusterIds;
import org.simantics.db.Database.Session.ResourceSegment;
import org.simantics.db.procore.cluster.ClusterTraits;
import org.simantics.db.service.ClusterSetsSupport;
import org.simantics.db.service.ClusterUID;
+import org.simantics.utils.FileUtils;
import org.simantics.utils.threads.logger.ITask;
import org.simantics.utils.threads.logger.ThreadLogger;
import org.slf4j.Logger;
private AtomicBoolean safeToMakeSnapshot = new AtomicBoolean(true);
private IllegalAcornStateException cause;
+ public synchronized void purge(ServiceLocator locator) throws IllegalAcornStateException {
+
+ try {
+
+ // Schedule writing of all data to disk
+ refreshHeadState();
+ // Wait for files to be written
+ synchronizeWorkingDirectory();
+
+ String currentDir = workingDirectory.getFileName().toString();
+ Path baseline = workingDirectory.resolveSibling(currentDir + "_baseline");
+
+ Files.createDirectories(baseline);
+
+ for(String clusterKey : state.clusters) {
+ String[] parts1 = clusterKey.split("#");
+ String[] parts = parts1[0].split("\\.");
+ String readDirName = parts1[1];
+ if(!readDirName.equals(currentDir)) {
+ String fileName = parts[0] + "." + parts[1] + ".cluster";
+ Path from = dbFolder.resolve(readDirName).resolve(fileName);
+ Path to = baseline.resolve(fileName);
+ System.err.println("purge copies " + from + " => " + to);
+ Files.copy(from, to, StandardCopyOption.COPY_ATTRIBUTES);
+ long first = new BigInteger(parts[0], 16).longValue();
+ long second = new BigInteger(parts[1], 16).longValue();
+ ClusterUID uuid = ClusterUID.make(first, second);
+ ClusterInfo info = clusterLRU.getWithoutMutex(uuid);
+ info.moveTo(baseline);
+ }
+ }
+
+ for (String fileKey : state.files) {
+ String[] parts = fileKey.split("#");
+ String readDirName = parts[1];
+ if(!readDirName.equals(currentDir)) {
+ String fileName = parts[0] + ".extFile";
+ Path from = dbFolder.resolve(readDirName).resolve(fileName);
+ Path to = baseline.resolve(fileName);
+ System.err.println("purge copies " + from + " => " + to);
+ Files.copy(from, to, StandardCopyOption.COPY_ATTRIBUTES);
+ FileInfo info = fileLRU.getWithoutMutex(parts[0]);
+ info.moveTo(baseline);
+ }
+ }
+
+ for (String fileKey : state.stream) {
+ String[] parts = fileKey.split("#");
+ String readDirName = parts[1];
+ if(!readDirName.equals(currentDir)) {
+ ClusterStreamChunk chunk = streamLRU.purge(parts[0]);
+ System.err.println("purge removes " + chunk);
+ }
+ }
+
+ // Change sets
+ for (String fileKey : state.cs) {
+ String[] parts = fileKey.split("#");
+ String readDirName = parts[1];
+ if(!readDirName.equals(currentDir)) {
+ Long revisionId = Long.parseLong(parts[0]);
+ ChangeSetInfo info = csLRU.purge(revisionId);
+ System.err.println("purge removes " + info);
+ }
+// Path readDir = dbFolder.resolve(parts[1]);
+// Long revisionId = Long.parseLong(parts[0]);
+// int offset = Integer.parseInt(parts[2]);
+// int length = Integer.parseInt(parts[3]);
+// ChangeSetInfo info = new ChangeSetInfo(csLRU, readDir, revisionId, offset, length);
+// csLRU.map(info);
+ }
+
+ state.tailChangeSetId = state.headChangeSetId;
+
+ makeSnapshot(locator, true);
+
+ Files.walk(dbFolder, 1).filter(Files::isDirectory).forEach(f -> tryPurgeDirectory(f));
+
+ } catch (IllegalAcornStateException e) {
+ notSafeToMakeSnapshot(e);
+ throw e;
+ } catch (IOException e) {
+ IllegalAcornStateException e1 = new IllegalAcornStateException(e);
+ notSafeToMakeSnapshot(e1);
+ throw e1;
+ } catch (AcornAccessVerificationException e) {
+ IllegalAcornStateException e1 = new IllegalAcornStateException(e);
+ notSafeToMakeSnapshot(e1);
+ throw e1;
+ }
+
+ }
+
+ void tryPurgeDirectory(Path f) {
+
+
+ System.err.println("purge deletes " + f);
+
+ String currentDir = f.getFileName().toString();
+ if(currentDir.endsWith("db"))
+ return;
+
+ if(currentDir.endsWith("_baseline"))
+ currentDir = currentDir.replace("_baseline", "");
+
+ int ordinal = Integer.parseInt(currentDir);
+ if(ordinal < mainState.headDir - 1) {
+ System.err.println("purge deletes " + f);
+ FileUtils.deleteDir(f.toFile());
+ }
+
+ }
+
public synchronized boolean makeSnapshot(ServiceLocator locator, boolean fullSave) throws IllegalAcornStateException {
try {
if (!safeToMakeSnapshot.get())
csLRU.persist(state.cs);
}
- private void persistHeadState() throws IOException {
+ private void synchronizeWorkingDirectory() throws IOException {
// Sync current working directory
Files.walk(workingDirectory, 1).filter(Files::isRegularFile).forEach(FileIO::uncheckedSyncPath);
+ }
+
+ private void persistHeadState() throws IOException {
+ synchronizeWorkingDirectory();
state.save(workingDirectory);
mainState.headDir++;
}
this.cause = t;
}
+ public long getTailChangeSetId() {
+ return state.tailChangeSetId;
+ }
+
}
import org.simantics.acorn.internal.ClusterChange;
import org.simantics.acorn.internal.ClusterUpdateProcessorBase;
import org.simantics.acorn.internal.UndoClusterUpdateProcessor;
+import org.simantics.acorn.lru.ClusterChangeSet.Entry;
import org.simantics.acorn.lru.ClusterInfo;
import org.simantics.acorn.lru.ClusterStreamChunk;
import org.simantics.acorn.lru.ClusterUpdateOperation;
-import org.simantics.acorn.lru.ClusterChangeSet.Entry;
import org.simantics.db.ClusterCreator;
import org.simantics.db.Database;
import org.simantics.db.ServiceLocator;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.SDBException;
import org.simantics.db.server.ProCoreException;
import org.simantics.db.service.LifecycleSupport;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.logging.TimeLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.map.hash.TLongObjectHashMap;
public class GraphClientImpl2 implements Database.Session {
-
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GraphClientImpl2.class);
public static final boolean DEBUG = false;
public final ClusterManager clusters;
mainProgram.mutex.release();
}
} catch (IllegalAcornStateException | ProCoreException e) {
- Logger.defaultLogError("Snapshotting failed", e);
+ LOGGER.error("Snapshotting failed", e);
unexpectedClose = true;
} catch (InterruptedException e) {
- Logger.defaultLogError("Snapshotting interrupted", e);
+ LOGGER.error("Snapshotting interrupted", e);
} finally {
try {
if(tr != null)
try {
support.close();
} catch (DatabaseException e1) {
- Logger.defaultLogError("Failed to close database as a safety measure due to failed snapshotting", e1);
+ LOGGER.error("Failed to close database as a safety measure due to failed snapshotting", e1);
}
}
} catch (ProCoreException e) {
- Logger.defaultLogError("Failed to end snapshotting write transaction", e);
+ LOGGER.error("Failed to end snapshotting write transaction", e);
}
}
}
@Override
public void close() throws ProCoreException {
- System.err.println("Closing " + this + " and mainProgram " + mainProgram);
+ LOGGER.info("Closing " + this + " and mainProgram " + mainProgram);
if(!closed && !isClosing) {
isClosing = true;
try {
clusters.state.headChangeSetId++;
return clusters.state.headChangeSetId;
} catch (SDBException e) {
- Logger.defaultLogError("Failed to undo cancelled transaction", e);
+ LOGGER.error("Failed to undo cancelled transaction", e);
throw new ProCoreException(e);
}
}
public boolean rolledback() {
return clusters.rolledback();
}
+
+ public void purge() throws IllegalAcornStateException {
+ clusters.purge(locator);
+ }
-
-
-
-
-
-
-
-
-
-
- ////////////////////////
-
-
-
-
-
-
-
-
-
-
-
-
+ public void purgeDatabase() {
+
+ if (isClosing || unexpectedClose)
+ return;
+
+ saver.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Transaction tr = null;
+ try {
+ // First take a write transaction
+ tr = askWriteTransaction(-1);
+ // Then make sure that MainProgram is idling
+ mainProgram.mutex.acquire();
+ try {
+ synchronized(mainProgram) {
+ if(mainProgram.operations.isEmpty()) {
+ purge();
+ } else {
+ // MainProgram is becoming busy again - delay snapshotting
+ return;
+ }
+ }
+ } finally {
+ mainProgram.mutex.release();
+ }
+ } catch (IllegalAcornStateException | ProCoreException e) {
+ LOGGER.error("Purge failed", e);
+ unexpectedClose = true;
+ } catch (InterruptedException e) {
+ LOGGER.error("Purge interrupted", e);
+ } finally {
+ try {
+ if(tr != null)
+ endTransaction(tr.getTransactionId());
+ if (unexpectedClose) {
+ LifecycleSupport support = getServiceLocator().getService(LifecycleSupport.class);
+ try {
+ support.close();
+ } catch (DatabaseException e1) {
+ LOGGER.error("Failed to close database as a safety measure due to failed purge", e1);
+ }
+ }
+ } catch (ProCoreException e) {
+ LOGGER.error("Failed to end purge write transaction", e);
+ }
+ }
+ }
+ });
+
+ }
+
+ public long getTailChangeSetId() {
+ return clusters.getTailChangeSetId();
+ }
+
}
import org.simantics.acorn.exception.InvalidHeadStateException;
import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdapterConstructionException;
import org.simantics.databoard.binding.mutable.MutableVariant;
import org.simantics.databoard.serialization.Serializer;
import org.simantics.databoard.util.binary.BinaryMemory;
public ArrayList<String> cs = new ArrayList<>();
// public ArrayList<String> ccs = new ArrayList<String>();
+ public long tailChangeSetId = 1;
+
public static HeadState load(Path directory) throws InvalidHeadStateException {
Path f = directory.resolve(HEAD_STATE);
return object;
}
} catch (IOException i) {
+ Throwable cause = i.getCause();
+ if(cause instanceof AdapterConstructionException) {
+ HeadState1 old = HeadState1.load(directory);
+ return old.migrate();
+ }
return new HeadState();
// throw new InvalidHeadStateException(i);
} catch (NoSuchAlgorithmException e) {
--- /dev/null
+package org.simantics.acorn;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.simantics.acorn.exception.InvalidHeadStateException;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.mutable.MutableVariant;
+import org.simantics.databoard.serialization.Serializer;
+import org.simantics.databoard.util.binary.BinaryMemory;
+
+public class HeadState1 {
+
+ public static final String HEAD_STATE = "head.state";
+ public static final String SHA_1 = "SHA-1";
+
+ public int headChangeSetId = 0;
+ public long transactionId = 1;
+ public long reservedIds = 3;
+
+ public ArrayList<String> clusters = new ArrayList<>();
+ public ArrayList<String> files = new ArrayList<>();
+ public ArrayList<String> stream = new ArrayList<>();
+ public ArrayList<String> cs = new ArrayList<>();
+
+ public HeadState migrate() {
+ HeadState state = new HeadState();
+ state.headChangeSetId = headChangeSetId;
+ state.transactionId = transactionId;
+ state.reservedIds = reservedIds;
+ state.clusters = clusters;
+ state.files = files;
+ state.stream = stream;
+ state.cs = cs;
+ return state;
+ }
+
+ public static HeadState1 load(Path directory) throws InvalidHeadStateException {
+ Path f = directory.resolve(HEAD_STATE);
+
+ try {
+ byte[] bytes = Files.readAllBytes(f);
+ MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
+ int digestLength = sha1.getDigestLength();
+
+ sha1.update(bytes, digestLength, bytes.length - digestLength);
+ byte[] newChecksum = sha1.digest();
+ if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
+ throw new InvalidHeadStateException(
+ "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
+ + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + f.toAbsolutePath());
+ }
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes, digestLength, bytes.length - digestLength)) {
+ HeadState1 object = (HeadState1) org.simantics.databoard.Files.readFile(bais, Bindings.getBindingUnchecked(HeadState1.class));
+ return object;
+ }
+ } catch (IOException i) {
+ return new HeadState1();
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error("SHA-1 Algorithm not found", e);
+ } catch (Throwable t) {
+ throw new InvalidHeadStateException(t);
+ }
+ }
+
+ public void save(Path directory) throws IOException {
+ Path f = directory.resolve(HEAD_STATE);
+ try {
+ BinaryMemory rf = new BinaryMemory(4096);
+ try {
+ MutableVariant v = new MutableVariant(Bindings.getBindingUnchecked(HeadState1.class), this);
+ Serializer s = Bindings.getSerializerUnchecked( Bindings.VARIANT );
+ s.serialize(rf, v);
+ } finally {
+ rf.close();
+ }
+
+ byte[] bytes = rf.toByteBuffer().array();
+
+ MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
+ sha1.update(bytes);
+ byte[] checksum = sha1.digest();
+
+ try (OutputStream out = Files.newOutputStream(f)) {
+ out.write(checksum);
+ out.write(bytes);
+ }
+ FileIO.syncPath(f);
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error("SHA-1 digest not found, should not happen", e);
+ }
+ }
+
+ public static void validateHeadStateIntegrity(Path headState) throws InvalidHeadStateException, IOException {
+ try {
+ byte[] bytes = Files.readAllBytes(headState);
+ MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
+ int digestLength = sha1.getDigestLength();
+ sha1.update(bytes, digestLength, bytes.length - digestLength);
+ byte[] newChecksum = sha1.digest();
+ if (!Arrays.equals(newChecksum, Arrays.copyOfRange(bytes, 0, digestLength))) {
+ throw new InvalidHeadStateException(
+ "Checksum " + Arrays.toString(newChecksum) + " does not match excpected "
+ + Arrays.toString(Arrays.copyOfRange(bytes, 0, digestLength)) + " for " + headState.toAbsolutePath());
+ }
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error("SHA-1 digest not found, should not happen", e);
+ }
+ }
+}
import org.simantics.db.DatabaseUserAgent;
import org.simantics.db.ServiceLocator;
import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.SDBException;
+import org.simantics.db.server.DatabaseStartException;
import org.simantics.db.server.ProCoreException;
+import org.simantics.db.server.internal.InternalException;
/**
* @author Tuukka Lehtonen
public class AcornDatabase implements Database {
private final Path folder;
+
+ private GraphClientImpl2 currentClient;
private DatabaseUserAgent userAgent;
@Override
public void purgeDatabase() throws ProCoreException {
- // TODO: implement
- throw new UnsupportedOperationException();
+ if(currentClient == null) throw new IllegalStateException("No current session.");
+ currentClient.purgeDatabase();
}
@Override
public long serverGetTailChangeSetId() throws ProCoreException {
- // "We have it all"
- // But after purging we don't so beware.
- // TODO: beware for purge
- return 1;
+ if(currentClient == null) throw new IllegalStateException("No current session.");
+ return currentClient.getTailChangeSetId();
}
@Override
public Session newSession(ServiceLocator locator) throws ProCoreException {
try {
- return new GraphClientImpl2(this, folder, locator);
+ if(currentClient != null) throw new DatabaseStartException(folder.toFile(), "A session is already running. Only one session is supported.");
+ currentClient = new GraphClientImpl2(this, folder, locator);
+ return currentClient;
} catch (IOException e) {
throw new ProCoreException(e);
}
import org.simantics.acorn.GraphClientImpl2;
import org.simantics.acorn.exception.AcornAccessVerificationException;
import org.simantics.acorn.exception.IllegalAcornStateException;
-import org.simantics.db.common.utils.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/*
* The order rule of synchronization for LRU and LRUObject is:
- * § Always lock LRUObject first!
+ * � Always lock LRUObject first!
*
*/
public class LRU<MapKey,MapValue extends LRUObject<MapKey, MapValue>> {
-
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LRU.class);
+
public static boolean VERIFY = true;
final private long swapTime = 5L*1000000000L;
}
}
+
+
+ public MapValue purge(MapKey id) {
+ return map.remove(id);
+ }
+
public MapValue get(MapKey key) throws AcornAccessVerificationException {
if(VERIFY) verifyAccess();
manager.notSafeToMakeSnapshot(new IllegalAcornStateException(t));
}
t.printStackTrace();
- Logger.defaultLogError(t);
+ LOGGER.error("Exception happened in WriteRunnable.run", t);
}
}
runWithMutex();
done = true;
} else {
- System.err.println("Retry mutex acquire");
+ LOGGER.warn("Retry mutex acquire");
gotMutex = impl.tryAcquireMutex();
}
if(VERIFY) verifyAccess();
return readDirectory;
}
+
+ public void moveTo(Path path) {
+ readDirectory = path;
+ }
}
\ No newline at end of file
all = searchByType model ANNO.AnnotationType
named = filter (\x -> (getAnnotationNameFromType x) == name) all
if ((length named) == 1)
- then Just (fromResource $ named!0)
+ then Just (named!0)
else Nothing
setAnnotationPropertyValue :: AnnotationPropertyRelation -> Resource -> String -> String -> <WriteGraph> ()
setAnnotationPropertyValue annotation resource property newValue = do
resourceUri = uriOf resource
- annotationName = DB.nameOf (toResource annotation)
+ annotationName = DB.nameOf annotation
completeUri = resourceUri + "#" + annotationName + "#" + property + "#HasDisplayValue"
propertyVariable = variable completeUri
setValue propertyVariable newValue
import org.eclipse.jface.resource.ColorDescriptor;
import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.simantics.browsing.ui.content.LabelDecorator;
import org.simantics.databoard.Bindings;
return font;
else {
FontDescriptor desc = (FontDescriptor)font;
+ if(desc == null) desc = FontDescriptor.createFrom(JFaceResources.getDialogFont().getFontData());
return (Font)desc.withStyle(style);
}
}
import org.simantics.browsing.ui.model.visuals.VisualsContribution;
import org.simantics.db.ReadGraph;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.exception.PendingVariableException;
/**
* Produces labels for nodes of given node type.
*/
public class LabelContribution extends VisualsContribution {
LabelRule labelRule;
-
+
public LabelContribution(NodeType nodeType, Test test, LabelRule labelRule, double priority) throws InvalidContribution {
super(nodeType, test, priority);
if(!labelRule.isCompatible(
throw new InvalidContribution("Label rule is not compatible with the content type.");
this.labelRule = labelRule;
}
-
+
/**
* Returns a label for the node or null, if contribution is
* not suitable for the input.
public Map<String, String> getLabel(ReadGraph graph, NodeContext context) {
Object content = context.getConstant(BuiltinKeys.INPUT);
try {
- if(test == null || test.test(graph, content))
+ if(test == null || test.test(graph, content))
return labelRule.getLabel(graph, content);
else
return null;
+ } catch(PendingVariableException e) {
+ return Collections.singletonMap(ColumnKeys.SINGLE, "");
} catch(DatabaseException e) {
ErrorLogger.defaultLogError(e);
- //Logger.defaultLogError(e);
- // TODO reconsider
return Collections.singletonMap(ColumnKeys.SINGLE, "");
}
- }
+ }
}
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.eclipse.core.runtime.Assert;
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum;
-import org.eclipse.nebula.widgets.nattable.selection.command.SelectCellCommand;
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.simantics.browsing.ui.swt.ViewerRowReference;
import org.simantics.browsing.ui.swt.internal.Threads;
import org.simantics.db.layer0.SelectionHints;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.MapList;
import org.simantics.utils.datastructures.disposable.AbstractDisposable;
import org.simantics.utils.datastructures.hints.IHintContext;
private boolean expand;
private boolean verticalBarVisible = false;
- private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {
+ private BiFunction<GraphExplorer, Object[], Object[]> selectionTransformation = new BiFunction<GraphExplorer, Object[], Object[]>() {
@Override
- public Object[] call(GraphExplorer explorer, Object[] objects) {
+ public Object[] apply(GraphExplorer explorer, Object[] objects) {
Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
IHintContext context = new AdaptableHintContext(SelectionHints.KEY_MAIN);
}
protected Object[] transformSelection(Object[] objects) {
- return selectionTransformation.call(this, objects);
+ return selectionTransformation.apply(this, objects);
}
protected static Object[] filter(SelectionFilter filter, NodeContext[] contexts) {
@Override
public void setSelectionTransformation(
- BinaryFunction<Object[], GraphExplorer, Object[]> f) {
+ BiFunction<GraphExplorer, Object[], Object[]> f) {
this.selectionTransformation = f;
}
com.lowagie.text;bundle-version="2.1.5",
org.simantics.scl.ui.editor;bundle-version="0.1.3";visibility:=reexport,
org.simantics.scl.compiler.dummy;bundle-version="0.1.3",
- org.eclipse.e4.core.contexts;bundle-version="1.4.0"
+ org.eclipse.e4.core.contexts;bundle-version="1.4.0",
+ org.slf4j.api;bundle-version="1.7.20"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.simantics.browsing.ui.swt,
org.simantics.browsing.ui.swt.contentassist,
package org.simantics.browsing.ui.swt;
import java.lang.reflect.Method;
+import java.util.function.BiFunction;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.SWT;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
import org.simantics.simulation.ontology.SimulationResource;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.hints.IHintContext;
import org.simantics.utils.ui.ExceptionUtils;
private IServiceLocator serviceLocator;
- private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {
+ private BiFunction<GraphExplorer, Object[], Object[]> selectionTransformation = new BiFunction<GraphExplorer, Object[], Object[]>() {
private Resource getModel(final Object object) {
if(object instanceof NodeContext) {
return null;
}
-
@Override
- public Object[] call(GraphExplorer explorer, Object[] objects) {
+ public Object[] apply(GraphExplorer explorer, Object[] objects) {
Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
IHintContext context = new AdaptableHintContext(SelectionHints.KEY_MAIN);
return this;
}
- public GraphExplorerFactory selectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {
+ public GraphExplorerFactory selectionTransformation(BiFunction<GraphExplorer, Object[], Object[]> transformation) {
this.selectionTransformation = transformation;
return this;
}
//GraphExplorerImpl2 explorer = new GraphExplorerImpl2(parent, style);
try {
Bundle bundle = Platform.getBundle("org.simantics.browsing.ui.nattable");
- Class<GraphExplorer> clazz = (Class<GraphExplorer>)bundle.loadClass("org.simantics.browsing.ui.nattable.NatTableGraphExplorer");
+ @SuppressWarnings("unchecked")
+ Class<GraphExplorer> clazz = (Class<GraphExplorer>)bundle.loadClass("org.simantics.browsing.ui.nattable.NatTableGraphExplorer");
//Class<GraphExplorer> clazz = (Class<GraphExplorer>)bundle.getClass().getClassLoader().loadClass("org.simantics.browsing.ui.nattable.NatTableGraphExplorer");
GraphExplorer explorer = clazz.getConstructor(Composite.class, int.class).newInstance(parent,style);
explorer.setSelectionDataResolver(selectionDataResolver);
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.eclipse.core.runtime.Assert;
import org.simantics.db.layer0.SelectionHints;
import org.simantics.utils.ObjectUtils;
import org.simantics.utils.datastructures.BijectionMap;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.disposable.AbstractDisposable;
import org.simantics.utils.datastructures.hints.IHintContext;
import org.simantics.utils.threads.IThreadWorkQueue;
protected BasePostSelectionProvider selectionProvider = new BasePostSelectionProvider();
protected SelectionDataResolver selectionDataResolver;
protected SelectionFilter selectionFilter;
- protected BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {
+ protected BiFunction<GraphExplorer, Object[], Object[]> selectionTransformation = new BiFunction<GraphExplorer, Object[], Object[]>() {
@Override
- public Object[] call(GraphExplorer explorer, Object[] objects) {
+ public Object[] apply(GraphExplorer explorer, Object[] objects) {
Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
IHintContext context = new AdaptableHintContext(SelectionHints.KEY_MAIN);
}
@Override
- public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> f) {
+ public void setSelectionTransformation(BiFunction<GraphExplorer, Object[], Object[]> f) {
this.selectionTransformation = f;
}
}
protected Object[] transformSelection(Object[] objects) {
- return selectionTransformation.call(this, objects);
+ return selectionTransformation.apply(this, objects);
}
protected static Object[] filter(SelectionFilter filter, NodeContext[] contexts) {
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.eclipse.core.runtime.Assert;
import org.simantics.db.layer0.SelectionHints;
import org.simantics.ui.SimanticsUI;
import org.simantics.utils.datastructures.BijectionMap;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.MapList;
import org.simantics.utils.datastructures.disposable.AbstractDisposable;
import org.simantics.utils.datastructures.hints.IHintContext;
private boolean expand;
private boolean verticalBarVisible = false;
- private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {
+ private BiFunction<GraphExplorer, Object[], Object[]> selectionTransformation = new BiFunction<GraphExplorer, Object[], Object[]>() {
@Override
- public Object[] call(GraphExplorer explorer, Object[] objects) {
+ public Object[] apply(GraphExplorer explorer, Object[] objects) {
Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
IHintContext context = new AdaptableHintContext(SelectionHints.KEY_MAIN);
}
protected Object[] transformSelection(Object[] objects) {
- return selectionTransformation.call(this, objects);
+ return selectionTransformation.apply(this, objects);
}
protected static Object[] filter(SelectionFilter filter, NodeContext[] contexts) {
@Override
public void setSelectionTransformation(
- BinaryFunction<Object[], GraphExplorer, Object[]> f) {
+ BiFunction<GraphExplorer, Object[], Object[]> f) {
this.selectionTransformation = f;
}
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.eclipse.core.runtime.IAdaptable;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
-import org.simantics.db.common.request.ResourceRead;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.request.PossibleVariable;
+import org.simantics.db.layer0.request.PossibleVariableRepresents;
import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
import org.simantics.db.management.ISessionContext;
import org.simantics.db.management.ISessionContextChangedListener;
import org.simantics.db.management.ISessionContextProvider;
import org.simantics.ui.selection.WorkbenchSelectionElement;
import org.simantics.ui.selection.WorkbenchSelectionUtils;
import org.simantics.utils.ObjectUtils;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.Function;
import org.simantics.utils.datastructures.disposable.DisposeState;
import org.simantics.utils.datastructures.hints.HintListenerAdapter;
import org.simantics.utils.datastructures.hints.IHintListener;
import org.simantics.utils.datastructures.hints.IHintObservable;
import org.simantics.utils.datastructures.hints.IHintTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class GraphExplorerComposite extends Composite implements Widget, IAdaptable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(GraphExplorerComposite.class);
+
protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor;
protected UserSelectedViewpointFactoryQueryProcessor userSelectedViewpointFactoryQueryProcessor;
protected FilterSelectionRequestQueryProcessor filterSelectionRequestQueryProcessor;
@SuppressWarnings("unchecked")
@Override
public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {
-
- if(wse != null) {
+ if (wse != null) {
T result = wse.getContent(contentType);
- if(result != null) return result;
+ if (result != null)
+ return result;
}
-
- if(contentType instanceof AnyResource) return (T)resource;
- else if(contentType instanceof AnyVariable) {
- AnyVariable type = (AnyVariable)contentType;
+
+ if (contentType instanceof AnyResource) {
+ if (resource != null)
+ return (T) resource;
+ if (variable == null)
+ return null;
+ try {
+ return (T) ((AnyResource) contentType).processor.syncRequest(new PossibleVariableRepresents(variable));
+ } catch (DatabaseException e) {
+ LOGGER.error("Unexpected error occurred while resolving Resource from Variable " + variable, e);
+ }
+ }
+ else if (contentType instanceof AnyVariable) {
+ if (variable != null)
+ return (T) variable;
+ if (resource == null)
+ return null;
try {
-
- if(variable != null) return (T)variable;
-
- if(resource == null) return null;
-
- return (T) type.processor.sync(new ResourceRead<Variable>(resource) {
- @Override
- public Variable perform(ReadGraph graph) throws DatabaseException {
- return Variables.getPossibleVariable(graph, resource);
- }
-
- });
+ return (T) ((AnyVariable) contentType).processor.syncRequest(new PossibleVariable(resource));
} catch (DatabaseException e) {
- Logger.defaultLogError(e);
+ LOGGER.error("Unexpected error occurred while resolving Variable from Resource " + resource, e);
}
} else if (contentType instanceof ExplorerInputContentType) {
- return (T)input;
+ return (T) input;
} else if (contentType instanceof ExplorerColumnContentType) {
- return (T)explorerState.getActiveColumn();
+ return (T) explorerState.getActiveColumn();
}
return null;
}
-
+
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class adapter) {
}
}
- private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {
+ private BiFunction<GraphExplorer, Object[], Object[]> selectionTransformation = new BiFunction<GraphExplorer, Object[], Object[]>() {
private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN };
@Override
- public Object[] call(GraphExplorer explorer, Object[] objects) {
+ public Object[] apply(GraphExplorer explorer, Object[] objects) {
Object[] result = new Object[objects.length];
for (int i = 0; i < objects.length; i++) {
SelectionElement context = new SelectionElement(explorer, KEYS, objects[i]);
event.data = WorkbenchSelectionUtils.getPossibleJSON(selectionProvider.getSelection());
} catch (DatabaseException e) {
event.data = "{ type:\"Exception\" }";
- Logger.defaultLogError(e);
+ LOGGER.error("Failed to get current selection as JSON.", e);
}
} else if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {
ls.dragSetData(event);
this.filterAreaSource = provider;
}
- public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {
+ public void setSelectionTransformation(BiFunction<GraphExplorer, Object[], Object[]> transformation) {
this.selectionTransformation = transformation;
if(explorer != null) explorer.setSelectionTransformation(transformation);
}
import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.eclipse.core.runtime.IAdaptable;
import org.simantics.browsing.ui.NodeContext.QueryKey;
import org.simantics.browsing.ui.content.Labeler;
import org.simantics.browsing.ui.content.Labeler.Modifier;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.threads.IThreadWorkQueue;
/**
*/
void setSelectionFilter(SelectionFilter f);
- void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> f);
+ void setSelectionTransformation(BiFunction<GraphExplorer, Object[], Object[]> f);
//ISelectionProvider getSelectionProvider();
Browses the given Model for its Charts and then returns them in a list.
"""
chartsOf :: Model -> <ReadGraph> [Chart]
-chartsOf model = recurse (toResource model)
+chartsOf model = recurse model
where
recurse r = do
- cs = resourceChildrenOf r
- charts = map fromResource $ filter isChart cs
+ cs = children r
+ charts = filter isChart cs
chartGrp = filter isChartGroup cs
charts + concatMap recurse chartGrp
isChart r = isInstanceOf r CHART.TimeSeriesChart
public static HistorySamplerItem createHistorySamplerItem(ReadGraph graph, Resource subscriptionItem, ChartData data) throws DatabaseException {
try {
- Resource model = graph.syncRequest(new PossibleIndexRoot(subscriptionItem));
- if (model == null) {
- throw new DatabaseException("There is no model for " + subscriptionItem);
+ Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(subscriptionItem));
+ if (indexRoot == null) {
+ throw new DatabaseException("There is no index root for " + subscriptionItem);
}
ItemManager im = new ItemManager(data.history.getItems());
*
* @author Tuukka Lehtonen
*/
-public class TrendSupport {
+public class TrendSupport implements ITrendSupport {
// Input
private IDynamicExperiment experiment;
return finalPath.toFile();
}
+ @Override
+ public void setChartData(ReadGraph graph) throws DatabaseException {
+ }
+
+ @Override
+ public ChartData getChartData() {
+ return chartData;
+ }
+
}
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.simantics.db.common;bundle-version="0.8.0",
org.eclipse.core.runtime;bundle-version="3.6.0",
- gnu.trove3;bundle-version="3.0.0"
+ gnu.trove3;bundle-version="3.0.0",
+ org.slf4j.api
Export-Package: org.simantics.db.impl,
org.simantics.db.impl.exception,
org.simantics.db.impl.graph,
import java.util.ArrayList;
import java.util.Iterator;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.impl.DebugPolicy;
import org.simantics.db.impl.graph.ReadGraphImpl;
import org.simantics.db.impl.procedure.InternalProcedure;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
abstract public class CacheEntryBase extends CacheEntry {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CacheEntryBase.class);
+
// Default level is something that is not quite a prospect but still allows for ordering within CacheCollectionResult
public static final short UNDEFINED_LEVEL = 5;
statusOrException = EXCEPTED;
result = t;
} else {
- Logger.defaultLogError("Cache entry got excepted status after being discarded: " + getClass().getSimpleName(), t);
+ LOGGER.warn("Cache entry got excepted status after being discarded: " + getClass().getSimpleName(), t);
result = t;
}
}
final public boolean assertPending() {
boolean result = isPending();
if(!result) {
- System.err.println("Assertion failed, expected pending, got " + statusOrException);
+ LOGGER.warn("Assertion failed, expected pending, got " + statusOrException);
}
return result;
}
}
}
- if(entry != null) entry.addOrSet(graph, graph.processor, new Integer(0));
- procedure.execute(graph, new Integer(0));
+ Integer zero = 0;
+ if(entry != null) entry.addOrSet(graph, graph.processor, zero);
+ procedure.execute(graph, zero);
}
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
+import java.util.ArrayList;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.indexing.internal.IndexChangedWriter;
import org.simantics.db.layer0.adapter.GenericRelationIndex;
import org.simantics.db.layer0.genericrelation.IndexedRelations;
import org.simantics.db.layer0.internal.SimanticsInternal;
return;
if (DEBUG)
System.out.println("Marking all indexes dirty");
- getAllDirtyFile().createNewFile();
+ File allDirtyFile = getAllDirtyFile();
+ if (allDirtyFile.createNewFile()) {
+ FileUtils.syncFile(allDirtyFile);
+ }
}
public static void clearAllDirty() throws IOException {
File indexBase = getIndexBaseLocation();
if (!indexBase.exists() || !indexBase.isDirectory())
return;
- delete(getAllDirtyFile());
forEachIndexPath(new Procedure<File, IOException>() {
@Override
public void execute(File indexPath) throws IOException {
- delete(getChangedFile(indexPath));
+ getChangedFile(indexPath).delete();
}
});
- }
+ getAllDirtyFile().delete();
+ }
+
/**
* Internal to indexing, invoked by {@link IndexedRelationsImpl} which
* doesn't want to throw these exceptions forward. Just log it.
*
* @param indexPath
*/
- static void markIndexChanged(File indexPath) {
- if (!indexPath.exists())
- throw new IllegalArgumentException("index path " + indexPath + " does not exist");
- if (!indexPath.isDirectory())
- throw new IllegalArgumentException("index path " + indexPath + " is not a directory");
+ static void markIndexChanged(Session session, File indexPath) {
+ if (DEBUG)
+ System.out.println("Marking index dirty: " + indexPath);
try {
- if (DEBUG)
- System.out.println("Marking index dirty: " + indexPath);
- getChangedFile(indexPath).createNewFile();
+ File changedFile = getChangedFile(indexPath);
+ // Mark change only once per DB session.
+ if (getIndexChangedWriter(session).markDirty(changedFile)) {
+ if (indexPath.mkdirs()) {
+ if (changedFile.createNewFile()) {
+ FileUtils.syncFile(changedFile);
+ }
+ }
+ }
} catch (IOException e) {
Logger.defaultLogError(e);
}
}
+ private static IndexChangedWriter getIndexChangedWriter(Session session) {
+ IndexChangedWriter writer = session.peekService(IndexChangedWriter.class);
+ if (writer == null) {
+ synchronized (IndexChangedWriter.class) {
+ if (writer == null)
+ session.registerService(IndexChangedWriter.class, writer = new IndexChangedWriter());
+ }
+ }
+ return writer;
+ }
+
public static void deleteAllIndexes() throws IOException {
File indexBase = DatabaseIndexing.getIndexBaseLocation();
- delete(indexBase);
+
+ ArrayList<String> filter = new ArrayList<>(2);
+ filter.add(getAllDirtyFile().getAbsolutePath());
+ filter.add(indexBase.getAbsolutePath());
+
+ FileUtils.deleteAllWithFilter(indexBase, filter);
+ FileUtils.deleteAll(indexBase);
}
public static void deleteIndex(final Resource relation, final Resource modelPart) throws DatabaseException {
public static void deleteIndex(File indexPath) throws IOException {
if (DEBUG)
System.out.println("Deleting index " + indexPath);
- delete(indexPath);
+
+ ArrayList<String> filter = new ArrayList<>(2);
+ filter.add(getChangedFile(indexPath).getAbsolutePath());
+ filter.add(indexPath.getAbsolutePath());
+
+ FileUtils.deleteAllWithFilter(indexPath, filter);
+ FileUtils.deleteAll(indexPath);
}
public static void validateIndexes() throws IOException {
// Make sure that index-base is a valid directory
if (DEBUG)
System.out.println(indexBase + " is not a directory! Removing it.");
- delete(indexBase);
+ FileUtils.deleteAll(indexBase);
indexBase.mkdirs();
return;
}
if (allDirtyFile.isFile()) {
if (DEBUG)
System.out.println("All indexes marked dirty, removing them.");
- delete(allDirtyFile);
deleteAllIndexes();
} else {
forEachIndexPath(new Procedure<File, IOException>() {
}
}
-
- private static void delete(File fileOrDir) throws IOException {
- if (fileOrDir.exists())
- FileUtils.deleteAll(fileOrDir);
- }
-
interface Procedure<T, E extends Throwable> {
void execute(T t) throws E;
}
try {
+ DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
if(!searcher.startAccess(null, processor.getSession(), true)) {
// Could not write index for some reason. Ignore and let the next index query reinitialize the index.
return;
}
searcher.insertIndex(progress.newChild(40), relation, 1, documents);
- DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
} catch (InvalidResourceReferenceException e) {
throw new IndexException(e);
LockHandle handle = lock(processor, Pair.make(relationResource, input), true);
try {
+ DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
if(!searcher.startAccess(null, processor.getSession(), true)) {
// Could not write index for some reason. Ignore and let the next index query reinitialize the index.
return;
}
searcher.removeIndex(progress.newChild(40), relation, processor, key, keyValues);
- DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
} catch (DatabaseException e) {
throw new IndexException(e);
try {
+ DatabaseIndexing.markIndexChanged(processor.getSession(), searcher.getIndexPath());
if(!searcher.startAccess(null, processor.getSession(), true)) {
// Could not write index for some reason. Ignore and let the next index query reinitialize the index.
return true;
}
- didChange = searcher.replaceIndex(progress.newChild(40), key, keyValues, relation, 1, documents);
- if(didChange)
- DatabaseIndexing.markIndexChanged(searcher.getIndexPath());
+ searcher.replaceIndex(progress.newChild(40), key, keyValues, relation, 1, documents);
} catch (InvalidResourceReferenceException e) {
throw new IndexException(e);
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.indexing.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An internal in-memory container for telling whether a certain index has been
+ * changed since the platform was last started up.
+ *
+ * @author Jussi Koskela
+ * @since 1.28.0
+ */
+public class IndexChangedWriter {
+ private Set<String> dirtyFiles = new HashSet<>();
+
+ public synchronized boolean markDirty(File dirtyFile) throws IOException {
+ return dirtyFiles.add(dirtyFile.getAbsolutePath());
+ }
+}
import org.simantics.graph.db.TransferableGraphImporter;
import org.simantics.graph.representation.Root;
import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.datastructures.Triple;
public class SharedOntologyImportAdvisor extends AbstractImportAdvisor2 {
}
Resource existing = graph.getPossibleResource(uri);
- if(existing != null) throw new DatabaseException("Shared library " + uri + " exists already.");
+ if(existing != null) {
+ if(graph.isInstanceOf(existing, L0.ExternalEntity)) {
+ created.put(r, existing);
+ addRootInfo(r, r.name, existing);
+ return null;
+ } else {
+ throw new DatabaseException("Shared library " + uri + " exists already.");
+ }
+ }
Resource type = graph.getPossibleResource(r.type);
if(type == null) {
public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process)
throws DatabaseException {
- graph.markUndoPoint();
- if(published) {
- XSupport xs = graph.getService(XSupport.class);
- xs.setServiceMode(false, true);
- }
-
- graph.setClusterSet4NewResource(graph.getRootLibrary());
- graph.flushCluster();
-
- for(Map.Entry<Root, Triple<Resource, Resource, List<String>>> entry : toCreate.entrySet()) {
-
- Triple<Resource, Resource, List<String>> recipe = entry.getValue();
-
- Resource base = recipe.first;
- for(int i=0;i<recipe.third.size()-1;i++) {
- Resource lib = graph.newResource();
- graph.claim(lib, L0.InstanceOf, null, L0.Library);
- graph.addLiteral(lib, L0.HasName, L0.NameOf, URIStringUtils.unescape( recipe.third.get(i) ), Bindings.STRING);
- graph.claim(base, L0.ConsistsOf, L0.PartOf, lib);
- base = lib;
- }
+ XSupport xs = graph.getService(XSupport.class);
- Resource lib = graph.newResource();
- graph.newClusterSet(lib);
- graph.setClusterSet4NewResource(lib);
- graph.claim(lib, L0.InstanceOf, null, recipe.second);
- String name = URIStringUtils.unescape( recipe.third.get(recipe.third.size()-1) );
- graph.addLiteral(lib, L0.HasName, L0.NameOf, name, Bindings.STRING);
- graph.claim(base, L0.ConsistsOf, L0.PartOf, lib);
+ Pair<Boolean,Boolean> mode = xs.getServiceMode();
+
+ try {
+
+ graph.markUndoPoint();
+
+ if(published) {
+ xs.setServiceMode(true, true);
+ } else {
+ xs.setServiceMode(true, mode.second);
+ }
+
+ graph.setClusterSet4NewResource(graph.getRootLibrary());
+ graph.flushCluster();
+
+ for(RootInfo info : getRootInfo()) {
+ // At this stage these are existing L0.ExternalEntity instances that are now being imported.
+ graph.deny(info.resource, L0.InstanceOf, null, L0.ExternalEntity, null);
+ }
+
+ for(Map.Entry<Root, Triple<Resource, Resource, List<String>>> entry : toCreate.entrySet()) {
+
+ Triple<Resource, Resource, List<String>> recipe = entry.getValue();
+
+ Resource base = recipe.first;
+ for(int i=0;i<recipe.third.size()-1;i++) {
+ Resource lib = graph.newResource();
+ graph.claim(lib, L0.InstanceOf, null, L0.Library);
+ graph.addLiteral(lib, L0.HasName, L0.NameOf, URIStringUtils.unescape( recipe.third.get(i) ), Bindings.STRING);
+ graph.claim(base, L0.ConsistsOf, L0.PartOf, lib);
+ base = lib;
+ }
+
+ Resource lib = graph.newResource();
+ graph.newClusterSet(lib);
+ graph.setClusterSet4NewResource(lib);
+ graph.claim(lib, L0.InstanceOf, null, recipe.second);
+ String name = URIStringUtils.unescape( recipe.third.get(recipe.third.size()-1) );
+ graph.addLiteral(lib, L0.HasName, L0.NameOf, name, Bindings.STRING);
+ graph.claim(base, L0.ConsistsOf, L0.PartOf, lib);
+
+ addRootInfo(entry.getKey(), name, lib);
+
+ created.put(entry.getKey(), lib);
+
+ }
+
+ graph.flushCluster();
+
+ } finally {
- addRootInfo(entry.getKey(), name, lib);
-
- created.put(entry.getKey(), lib);
-
- }
-
- graph.flushCluster();
+ xs.setServiceMode(mode.first, mode.second);
+
+ }
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.layer0.migration;
+
+import java.util.Collection;
+
+import org.simantics.db.Resource;
+import org.simantics.db.exception.AssumptionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.graph.db.ImportResult;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class MigratedImportResult {
+
+ /**
+ * The root resources created by the import process.
+ */
+ public final Collection<Resource> roots;
+
+ public final ImportResult tgResult;
+
+ public MigratedImportResult(Collection<Resource> roots, ImportResult tgResult) {
+ this.roots = roots;
+ this.tgResult = tgResult;
+ }
+
+ public Resource singleRoot() throws DatabaseException {
+ int s = roots.size();
+ if (s != 1)
+ throw new AssumptionException("No single imported root found, roots are: " + roots);
+ return roots.iterator().next();
+ }
+
+ public boolean hasMissingExternals() {
+ return tgResult != null ? tgResult.hasMissingExternals() : false;
+ }
+
+}
import org.simantics.db.layer0.internal.SimanticsInternal;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.TGTransferableGraphSource;
import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
import org.simantics.db.request.Read;
import org.simantics.db.service.ManagementSupport;
import org.simantics.db.service.SerialisationSupport;
import org.simantics.graph.db.IImportAdvisor;
import org.simantics.graph.db.IImportAdvisor2;
+import org.simantics.graph.db.ImportResult;
import org.simantics.graph.db.StreamingTransferableGraphFileReader;
import org.simantics.graph.db.TGStatusMonitor;
import org.simantics.graph.db.TransferableGraphImporter;
};
// Make sure that the supplied advisor is redirected to temp
advisor.redirect(indexRoot);
-
- TransferableGraphs.importGraph1WithMonitor(session, tg, advisor, new TGStatusMonitor() {
+
+ ImportResult ir = TransferableGraphs.importGraph1(session, new TGTransferableGraphSource(tg), advisor, new TGStatusMonitor() {
@Override
public void status(int percentage) {
monitor.subTask("Importing model from file (" + percentage + "%)");
return monitor.isCanceled();
}
});
-
+
+ setProperty(MigrationStateKeys.IMPORT_RESULT, ir);
setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);
setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));
setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());
// Make sure that the supplied advisor is redirected to temp
advisor.redirect(indexRoot);
- TransferableGraphs.importGraph1(session, tgs, advisor, new TGStatusMonitor() {
+ ImportResult ir = TransferableGraphs.importGraph1(session, tgs, advisor, new TGStatusMonitor() {
@Override
public void status(int percentage) {
monitor.subTask("Importing model from file (" + percentage + "%)");
}
});
+ setProperty(MigrationStateKeys.IMPORT_RESULT, ir);
setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);
setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));
setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());
import org.eclipse.core.runtime.IProgressMonitor;
import org.simantics.db.Session;
+import org.simantics.graph.db.ImportResult;
public interface MigrationStateKeys {
public final static String TG_EXTENSIONS = "tgExtensions";
public final static String CURRENT_RESOURCE = "currentResource";
public final static String IMPORT_ADVISOR = "importAdvisor";
+
+ /**
+ * Used for storing the {@link ImportResult} resulting from the TG import.
+ */
+ public final static String IMPORT_RESULT = "importResult";
+
/**
* All root resources of the imported material as
* Collection<Resource>.
*******************************************************************************/
package org.simantics.db.layer0.migration;
+import java.io.DataInputStream;
import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
import org.simantics.databoard.binding.mutable.Variant;
import org.simantics.databoard.container.DataContainer;
+import org.simantics.databoard.container.DataContainers;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.WriteGraph;
import org.simantics.db.WriteOnlyGraph;
import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.primitiverequest.PossibleResource;
import org.simantics.db.common.request.BinaryRead;
import org.simantics.db.common.request.FreshEscapedName;
import org.simantics.db.common.request.UnaryRead;
import org.simantics.db.layer0.adapter.impl.SharedOntologyImportAdvisor;
import org.simantics.db.layer0.adapter.impl.TrashBinRemover;
import org.simantics.db.layer0.internal.SimanticsInternal;
+import org.simantics.db.layer0.util.ExternalDownloadBean;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.util.TGTransferableGraphSource;
import org.simantics.db.service.XSupport;
import org.simantics.graph.db.IImportAdvisor;
+import org.simantics.graph.db.ImportResult;
import org.simantics.graph.db.MissingDependencyException;
import org.simantics.graph.db.TransferableGraphException;
import org.simantics.graph.representation.Identity;
}
- @SuppressWarnings("deprecation")
public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {
return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {
return t != null ? t : defaultValue;
}
- public static Resource importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
+ public static MigratedImportResult importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
return importSharedOntology(null, session, tg, published);
}
- public static Resource importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
+ public static MigratedImportResult importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
if(monitor == null) monitor = new NullProgressMonitor();
+ Variant edbVariant = tg.extensions.get(ExternalDownloadBean.EXTENSION_KEY);
+ if(edbVariant != null) {
+ try {
+ ExternalDownloadBean edb = (ExternalDownloadBean)edbVariant.getValue(ExternalDownloadBean.BINDING);
+ for(Map.Entry<String, String> entry : edb.downloads.entrySet()) {
+ String uri = entry.getKey();
+ Resource existing = session.syncRequest(new PossibleResource(uri));
+ if(existing == null) {
+ String download = entry.getValue();
+ URL url = new URL(download);
+ DataContainer container = DataContainers.readFile(new DataInputStream(url.openStream()));
+ TransferableGraph1 dependencyTg = (TransferableGraph1) container.content.getValue(TransferableGraph1.BINDING);
+ importSharedOntology(monitor, session, dependencyTg, true);
+ }
+ }
+ } catch (AdaptException e) {
+ throw new DatabaseException(e);
+ } catch (MalformedURLException e) {
+ throw new DatabaseException(e);
+ } catch (IOException e) {
+ throw new DatabaseException(e);
+ }
+
+ }
+
Collection<Identity> roots = TransferableGraphUtils.getRoots(tg);
if(roots.size() == 1) {
-// Identity id = roots.iterator().next();
-// final Root root = (Root)id.definition;
-// Resource rootResource = session.syncRequest(new WriteResultRequest<Resource>() {
-// @Override
-// public Resource perform(WriteGraph graph) throws DatabaseException {
-// Resource type = graph.getResource(root.type);
-// Resource existing = graph.getPossibleResource(root.name);
-// if(existing != null) throw new DatabaseException("Shared library " + root.name + " exists already.");
-// return Layer0Utils.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, root.name, type);
-// }
-// });
try {
-
TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);
SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);
-// TransferableGraphs.importGraph1(session, tgSource, advisor);
-
-// if (advisor.getRoots().size() == 1) {
-// return advisor.getRoots().iterator().next();
-// }
- //TransferableGraphs.importGraph1(session, tg, new SharedOntologyImportAdvisor(), null);
MigrationState state = newState();
- //state.setProperty(MigrationStateKeys.BASE_URI, AprosBuiltins.URIs.Migration);
state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, false);
state.setProperty(MigrationStateKeys.CURRENT_TGS, tgSource);
state.setProperty(MigrationStateKeys.SESSION, session);
state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
state.setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, new DataContainer("sharedLibrary", 1, new Variant(TransferableGraph1.BINDING, tg)));
- return MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);
-
+ MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);
+
+ Collection<Resource> resultRoots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
+ ImportResult result = state.getProperty(MigrationStateKeys.IMPORT_RESULT);
+ return new MigratedImportResult(resultRoots, result);
} catch (TransferableGraphException e) {
throw new DatabaseException(e);
} catch (MissingDependencyException e) {
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.layer0.request;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class PossibleVariableRepresents extends VariableRead<Resource> {
+
+ public PossibleVariableRepresents(Variable var) {
+ super(var);
+ }
+
+ @Override
+ public Resource perform(ReadGraph graph) throws DatabaseException {
+ return variable.getPossibleRepresents(graph);
+ }
+
+}
package org.simantics.db.layer0.util;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import org.simantics.db.AsyncReadGraph;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
+import org.simantics.db.ResourceMap;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
import org.simantics.db.procedure.AsyncContextMultiProcedure;
-import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.procedure.Procedure;
import org.simantics.db.service.DirectQuerySupport;
import org.simantics.layer0.Layer0;
class ConsistsOfProcess {
- final Set<Resource> result;
- final AsyncContextMultiProcedure<Resource, Resource> structure;
+ final List<InternalEntry> result;
+ final AsyncContextMultiProcedure<InternalEntry, Resource> structure;
+ final AsyncContextMultiProcedure<InternalEntry, Resource> names;
- public static Set<Resource> walk(ReadGraph graph, Collection<Resource> resources, Set<Resource> exclusions, boolean ignoreVirtual) throws DatabaseException {
- ConsistsOfProcess process = new ConsistsOfProcess(graph, resources, exclusions, ignoreVirtual);
+ public static List<InternalEntry> walk(ReadGraph graph, ResourceMap<ExtentStatus> status, Collection<Resource> resources, Set<Resource> exclusions, boolean ignoreVirtual) throws DatabaseException {
+ ConsistsOfProcess process = new ConsistsOfProcess(graph, status, resources, exclusions, ignoreVirtual);
return process.result;
}
+
+ static class InternalEntry {
+ public InternalEntry parent;
+ public Resource resource;
+ public String name;
+ InternalEntry(InternalEntry parent, Resource resource, String name) {
+ this.parent = parent;
+ this.resource = resource;
+ this.name = name;
+ }
+ }
- private ConsistsOfProcess(ReadGraph graph, final Collection<Resource> resources, final Set<Resource> exclusions, final boolean ignoreVirtual) throws DatabaseException {
+ private ConsistsOfProcess(ReadGraph graph, ResourceMap<ExtentStatus> status, final Collection<Resource> resources, final Set<Resource> exclusions, final boolean ignoreVirtual) throws DatabaseException {
final Layer0 L0 = Layer0.getInstance(graph);
final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
- CollectionSupport cs = graph.getService(CollectionSupport.class);
- result = cs.createSet();
+ result = new ArrayList<InternalEntry>();
+
+ names = dqs.compileForEachObject(graph, L0.HasName, new AsyncContextMultiProcedure<InternalEntry, Resource>() {
+
+ @Override
+ public void execute(AsyncReadGraph graph, InternalEntry entry, Resource nameResource) {
+
+ if(status != null)
+ status.put(nameResource, ExtentStatus.EXCLUDED);
+
+ graph.forPossibleValue(nameResource, new Procedure<String>() {
+
+ @Override
+ public void execute(String result) {
+ entry.name = result;
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ Logger.defaultLogError(t);
+ }
+
+ });
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ Logger.defaultLogError(throwable);
+ }
+
+ @Override
+ public void finished(AsyncReadGraph graph) {
+ }
+
+ });
- structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure<Resource, Resource>() {
+ structure = dqs.compileForEachObject(graph, L0.ConsistsOf, new AsyncContextMultiProcedure<InternalEntry, Resource>() {
@Override
- public void execute(AsyncReadGraph graph, Resource parent, Resource child) {
+ public void execute(AsyncReadGraph graph, InternalEntry parent, Resource child) {
if(exclusions.contains(child)) return;
- if(!ignoreVirtual || child.isPersistent())
- if(result.add(child)) {
- dqs.forEachObjectCompiled(graph, child, child, structure);
+ if(!ignoreVirtual || child.isPersistent()) {
+ InternalEntry entry = new InternalEntry(parent, child, null);
+ if(result.add(entry)) {
+ dqs.forEachObjectCompiled(graph, child, entry, structure);
+ dqs.forEachObjectCompiled(graph, child, entry, names);
}
+ }
}
@Override
public void run(ReadGraph graph) throws DatabaseException {
- for(Resource r : resources)
- dqs.forEachObjectCompiled(graph, r, r, structure);
+ for(Resource r : resources) {
+ InternalEntry root = new InternalEntry(null, r, null);
+ dqs.forEachObjectCompiled(graph, r, root, structure);
+ }
}
});
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.simantics.db.exception.CancelTransactionException;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
+import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry;
import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest.Expansion3;
import org.simantics.db.service.CollectionSupport;
import org.simantics.db.service.SerialisationSupport;
this.datatypeBinding = Bindings.getBindingUnchecked(Datatype.class);
this.datatypeSerializer = graph.getService(Databoard.class).getSerializerUnchecked(this.datatypeBinding);
- for(Resource r : ConsistsOfProcess.walk(graph, fringe, exclusions, ignoreVirtual)) {
+ state.internalEntries = ConsistsOfProcess.walk(graph, status, fringe, exclusions, ignoreVirtual);
+
+ for(InternalEntry entry : state.internalEntries) {
+ Resource r = entry.resource;
if (status.put(r, ExtentStatus.INTERNAL) == null) {
if(ModelTransferableGraphSourceRequest.LOG) {
String URI = graph.getPossibleURI(r);
package org.simantics.db.layer0.util;
import java.io.DataOutputStream;
+import java.util.List;
import java.util.TreeMap;
import org.eclipse.core.runtime.SubMonitor;
public SubMonitor monitor;
public TGValueModifier valueModifier;
+ public List<ConsistsOfProcess.InternalEntry> internalEntries;
}
\ No newline at end of file
String name = URIStringUtils.unescape(escapedName);
parent = graph.syncRequest(new UnescapedChildMapOfResource(parent)).get(name);
if(parent == null)
- throw new DatabaseException("Didn't find a child " + name);
+ throw new DatabaseException("Didn't find a child " + name + " for " + uri.substring(0, beginPos));
}
else if(c == '#') {
String escapedName = uri.substring(beginPos+1, endPos);
--- /dev/null
+package org.simantics.db.layer0.util;
+
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+
+public class ExternalDownloadBean {
+
+ public static final String EXTENSION_KEY = ExternalDownloadBean.class.getSimpleName();
+
+ public static final Binding BINDING = Bindings.getBindingUnchecked(ExternalDownloadBean.class);
+
+ public TreeMap<String,String> downloads = new TreeMap<>();
+
+ public ExternalDownloadBean(TreeMap<String,String> downloads) {
+ this.downloads = downloads;
+ }
+
+}
import java.util.TreeSet;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.simantics.databoard.Bindings;
import org.simantics.databoard.Datatypes;
return Layer0.getInstance(graph).String;
}
+ public static void emptyTrashBin() throws ServiceException {
+ emptyTrashBin(new NullProgressMonitor());
+ }
+
public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException {
emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject());
}
return;
mon.subTask("Purging Database");
mon.newChild(1000);
- XSupport xs = session.getService(XSupport.class);
- xs.purge();
+ purgeDatabase(monitor, session);
} catch (CancelTransactionException e) {
// Ignore.
} catch (DatabaseException e) {
throw new ServiceException(e);
}
}
-
+
+ public static void purgeDatabase() throws ServiceException {
+ purgeDatabase(new NullProgressMonitor());
+ }
+
+ public static void purgeDatabase(final IProgressMonitor monitor) throws ServiceException {
+ purgeDatabase(monitor, SimanticsInternal.getSession());
+ }
+
+ public static void purgeDatabase(final IProgressMonitor monitor, Session session) throws ServiceException {
+ try {
+ XSupport xs = session.getService(XSupport.class);
+ xs.purge();
+ } catch (DatabaseException e) {
+ throw new ServiceException(e);
+ }
+ }
+
public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException {
Resource result = null;
for(Resource candidate : getDomainOf(graph, type).values()) {
return null;
}
+ public static Resource getPossiblePredicateByLabel(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ for(Resource type : graph.getPrincipalTypes(instance)) {
+ Map<String, Resource> domainOf = getDomainOf(graph, type);
+ for(Resource r : domainOf.values()) {
+ String label = graph.getPossibleRelatedValue(r, L0.HasLabel, Bindings.STRING);
+ if(predicateName.equals(label))
+ return r;
+ }
+ }
+ return null;
+ }
public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {
import org.simantics.db.exception.RuntimeDatabaseException;
import org.simantics.db.exception.ValidationException;
import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
+import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry;
import org.simantics.db.layer0.util.TransferableGraphConfiguration2.RootSpec;
import org.simantics.db.service.SerialisationSupport;
import org.simantics.graph.db.TransferableGraphSource;
import org.simantics.graph.representation.External;
import org.simantics.graph.representation.Identity;
+import org.simantics.graph.representation.Internal;
import org.simantics.graph.representation.Root;
import org.simantics.graph.representation.Value;
import org.simantics.layer0.Layer0;
import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.procedure.TIntIntProcedure;
public class ModelTransferableGraphSource implements TransferableGraphSource {
private volatile boolean closed = false;
TIntArrayList externalParents = new TIntArrayList();
- ArrayList<String> externalNames = new ArrayList<String>();
+ ArrayList<String> externalNames = new ArrayList<>();
+ TreeMap<String,String> downloads = new TreeMap<String,String>();
public ModelTransferableGraphSource(final ReadGraph graph, TransferableGraphConfiguration2 configuration, final DomainProcessorState state, File ... fs) throws DatabaseException {
this.externalBase = state.id;
- final Collection<String> errors = new HashSet<String>();
+ final Collection<String> errors = new HashSet<>();
// All resource considered as not internal by domain processor. Can also contain roots.
int[] externals = state.externals.toArray();
});
if(!errors.isEmpty()) {
- ArrayList<String> sorted = new ArrayList<String>(errors);
+ ArrayList<String> sorted = new ArrayList<>(errors);
Collections.sort(sorted);
StringBuilder message = new StringBuilder();
message.append("Errors in exported model:\n");
this.resourceCount = state.id;
+ state.extensions.put(ExternalDownloadBean.EXTENSION_KEY, new Variant(ExternalDownloadBean.BINDING, new ExternalDownloadBean(downloads)));
+
}
int indent = 0;
state.ids.put(r, state.id);
// Ensure that this resource is included into the set of externals to maintain the total number of externals
state.externals.add(r);
+ String download = graph.getPossibleRelatedValue(res, L0.Ontology_download, Bindings.STRING);
+ if(download != null) {
+ String uri = graph.getURI(res);
+ downloads.put(uri, download);
+ }
return state.id++;
}
}
// TODO: this should be Root with name ""
procedure.execute(getRootIdentity(state, support, graph.getRootLibrary()));
+ TIntObjectMap<Identity> internalMap = new TIntObjectHashMap<>(100, 0.5f, Integer.MIN_VALUE);
+
// Declare internal and external roots
for(RootSpec r : configuration.roots) {
Resource type = graph.getPossibleType(r.resource, L0.Entity);
if(type == null) type = L0.Entity;
- procedure.execute(new Identity(
- state.ids.get(support.getTransientId(r.resource)),
- new Root(r.name, graph.getURI(type))));
+ int id = state.ids.get(support.getTransientId(r.resource));
+ Root root = new Root(r.name, graph.getURI(type));
+ Identity rootId = new Identity(id,root);
+ internalMap.put(id, rootId);
+ procedure.execute(rootId);
}
for(int i = 0; i < state.externals.size() ; i++) {
String name = externalNames.get(i);
procedure.execute(new Identity(externalBase + i, new External(parent,name)));
}
+
+ if(state.internalEntries != null) {
+ for(InternalEntry ie : state.internalEntries) {
+ if(ie.parent != null && ie.name != null) {
+ procedure.execute(resolveInternal(graph, support, ie, internalMap));
+ }
+ }
+ }
}
+
+ private Identity resolveInternal(ReadGraph graph, SerialisationSupport ss, InternalEntry entry, TIntObjectMap<Identity> internalMap) throws DatabaseException {
+ int id = state.ids.get(ss.getTransientId(entry.resource));
+ Identity existing = internalMap.get(id);
+ if(existing != null) return existing;
+ Identity parent = resolveInternal(graph, ss, entry.parent, internalMap);
+ Identity result = new Identity(id,
+ new Internal(parent.resource, entry.name));
+ internalMap.put(id, result);
+ return result;
+ }
@Override
public TreeMap<String, Variant> getExtensions() {
*******************************************************************************/
package org.simantics.db.layer0.util;
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.TIntIntHashMap;
-import gnu.trove.map.hash.TLongObjectHashMap;
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.procedure.TLongObjectProcedure;
-import gnu.trove.set.TIntSet;
-import gnu.trove.set.hash.THashSet;
-import gnu.trove.set.hash.TIntHashSet;
-
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.SubgraphAdvisor;
import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
+import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry;
import org.simantics.db.procedure.AsyncProcedure;
import org.simantics.db.request.AsyncRead;
import org.simantics.db.service.ClusteringSupport;
import org.simantics.utils.threads.logger.ITask;
import org.simantics.utils.threads.logger.ThreadLogger;
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntIntHashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.procedure.TLongObjectProcedure;
+import gnu.trove.set.TIntSet;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
public class Subgraphs {
public static String LOG_FILE = "export.log";
* � All o are internal
* � All stm are included
*/
- for(Resource r : ConsistsOfProcess.walk(graph, fringe, exclusions, true)) {
+ List<InternalEntry> entries = ConsistsOfProcess.walk(graph, null, fringe, exclusions, true);
+ for(InternalEntry entry : entries) {
+ Resource r = entry.resource;
if (status.put(r, ExtentStatus.INTERNAL) == null) {
String URI = graph.getPossibleURI(r);
if(URI != null) log("URI INTERNAL " + URI);
import org.simantics.db.common.request.PossibleIndexRoot;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
+import org.simantics.db.layer0.util.ConsistsOfProcess.InternalEntry;
import org.simantics.db.layer0.util.DomainProcessor3.ExclusionDecision;
import org.simantics.layer0.Layer0;
import org.simantics.scl.runtime.function.Function1;
return new GUIDExclusionFunction(graph);
// The root is OK - check everything beneath
- for(Resource part : ConsistsOfProcess.walk(graph, Collections.singleton(r), Collections.emptySet(), true)) {
- if(findByIdentifier(graph, targetRoot, part))
+ List<InternalEntry> entries = ConsistsOfProcess.walk(graph, null, Collections.singleton(r), Collections.emptySet(), true);
+ for(InternalEntry entry : entries) {
+ if(findByIdentifier(graph, targetRoot, entry.resource))
return new GUIDExclusionFunction(graph);
}
}
import org.simantics.db.service.ClusterUID;
import org.simantics.db.service.SerialisationSupport;
import org.simantics.db.service.XSupport;
+import org.simantics.utils.datastructures.Pair;
public class XSupportImpl implements XSupport {
final private boolean DEBUG = false;
session.clusterSetsSupport.clear();
}
}
+
+ @Override
+ public Pair<Boolean, Boolean> getServiceMode() {
+ return Pair.make((session.serviceMode & 1) == 1, (session.serviceMode & 2) == 2);
+ }
+
@Override
public Resource convertDelayedResourceToResource(Resource resource) {
return DelayedWriteGraph.convertDelayedResource(resource);
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.ServiceException;
import org.simantics.db.request.WriteTraits;
+import org.simantics.utils.datastructures.Pair;
/**
* @author TUOKSK
* @param createAsImmutable <code>true</code> to make all created clusters immutable
*/
void setServiceMode(boolean allowImmutableWrites, boolean createAsImmutable);
+ Pair<Boolean,Boolean> getServiceMode();
/**
* If resource is acquired from DelayedWriteGraph during delayed write request then
org.simantics.db.layer0;bundle-version="[1.0.0,2.0.0)",
org.simantics.structural2;bundle-version="1.0.0",
org.simantics.basicexpression;bundle-version="1.0.0",
- javax.vecmath;bundle-version="1.0.0",
+ org.apache.commons.math3;bundle-version="3.6.1",
org.simantics.layer0;bundle-version="1.0.0",
org.simantics.diagram.ontology;bundle-version="1.0.0";visibility:=reexport,
org.simantics.structural.ontology;bundle-version="1.0.0",
import java.util.List;
import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
import org.simantics.g2d.element.ElementUtils;
import org.simantics.g2d.element.IElement;
import org.simantics.g2d.element.SceneGraphNodeKey;
SingleElementNode holder = node.getOrCreateNode(ElementUtils.generateNodeId(e), SingleElementNode.class);
//SingleElementNode holder = parent.getOrCreateNode(ElementUtils.generateNodeId(e), SingleElementNode.class);
holder.setZIndex(++zIndex);
+ holder.setKey(e.getHint(ElementHints.KEY_OBJECT));
List<SceneGraph> nodeHandlers = ec.getItemsByClass(SceneGraph.class);
for(SceneGraph n : nodeHandlers) {
DefaultTransform.INSTANCE,
StaticSymbolImageInitializer.INSTANCE,
new StaticSymbolImpl(img),
- ImageClass.ImageElementHandler.INSTANCE,
- new Terminals(terminals),
+ DefinedElementHandler.INSTANCE,
+ new DefinedElementTerminals(terminals),
SimpleElementLayers.INSTANCE,
PlainElementPropertySetter.INSTANCE
).setId(id));
--- /dev/null
+package org.simantics.diagram.adapter;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.g2d.connection.handler.ConnectionHandler;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.SceneGraphNodeKey;
+import org.simantics.g2d.element.handler.InternalSize;
+import org.simantics.g2d.element.handler.Outline;
+import org.simantics.g2d.element.handler.Resize;
+import org.simantics.g2d.element.handler.SceneGraph;
+import org.simantics.g2d.image.Image;
+import org.simantics.scenegraph.Node;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+
+public class DefinedElementHandler implements SceneGraph, InternalSize, Resize, Outline {
+
+ private static final long serialVersionUID = -2074850877791708846L;
+
+ public static final DefinedElementHandler INSTANCE = new DefinedElementHandler();
+
+ public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "IMAGE_SG_NODE");
+
+ protected Image getImage(IElement e) {
+ Image i = e.getHint(ElementHints.KEY_IMAGE);
+ if (i == null)
+ throw new IllegalStateException("element " + e + " has no ElementHints.KEY_IMAGE hint");
+ return i;
+ }
+
+ protected Key getNodeKey() {
+ return KEY_SG_NODE;
+ }
+
+ @Override
+ public void init(final IElement e, final G2DParentNode parent) {
+ Image i = getImage(e);
+ Node node = i.init(parent);
+ if (node != null)
+ e.setHint(getNodeKey(), node);
+ if(node instanceof IG2DNode) {
+ IG2DNode n = (IG2DNode)node;
+ AffineTransform at = ElementUtils.getTransform(e);
+ if(at != null) {
+ n.setTransform(at); // FIXME: not tested..
+ }
+ }
+ }
+
+ public void cleanup(final IElement e) {
+ Node node = e.removeHint(getNodeKey());
+ if (node != null)
+ node.remove();
+ }
+
+ public Rectangle2D imageBounds(IElement e) {
+ Image i = getImage(e);
+ return i.getBounds();
+ }
+
+ @Override
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {
+
+ if (size == null)
+ size = new Rectangle2D.Double();
+
+ ElementClass ec = e.getElementClass();
+ if(ec.containsClass(ConnectionHandler.class)) {
+ size.setFrame(imageBounds(e));
+ } else {
+ IG2DNode node = e.getHint(getNodeKey());
+ if(node != null) {
+ size.setFrame(node.getBoundsInLocal());
+ } else {
+ size.setFrame(imageBounds(e));
+ }
+ }
+
+ return size;
+
+ }
+
+ @Override
+ public Double getFixedAspectRatio(IElement e) {
+ Image i = getImage(e);
+ Rectangle2D r = i.getBounds();
+ return r.getWidth() / r.getHeight();
+ }
+
+ @Override
+ public Rectangle2D getMaximumSize(IElement e) {
+ Image i = getImage(e);
+ return i.getBounds();
+ }
+
+ @Override
+ public Rectangle2D getMinimumSize(IElement e) {
+ Image i = getImage(e);
+ return i.getBounds();
+ }
+
+ @Override
+ public void resize(IElement e, Rectangle2D newSize) {
+ }
+
+ @Override
+ public Shape getElementShape(IElement e) {
+
+ IG2DNode node = e.getHint(getNodeKey());
+ if (node == null)
+ throw new IllegalStateException();
+ return node.getBoundsInLocal();
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - #7119 initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.adapter;
+
+import java.awt.geom.AffineTransform;
+import java.util.Collection;
+
+import org.simantics.diagram.content.ResourceTerminal;
+import org.simantics.g2d.diagram.handler.Topology.Terminal;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.TerminalLayout;
+import org.simantics.g2d.element.handler.TerminalTopology;
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;
+import org.simantics.g2d.element.handler.impl.Terminals;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.utils.NodeUtil;
+
+/**
+ * A {@link TerminalTopology} and more specifically a {@link TerminalLayout}
+ * implementation that relies primarily on the scene graph and only secondarily
+ * on its internal datastructures to resolve terminal locations. This implementation
+ * is used to support dynamic terminals.
+ *
+ * @author Antti Villberg
+ * @since 1.29.0
+ */
+public class DefinedElementTerminals extends Terminals {
+
+ private static final long serialVersionUID = -726490868093887444L;
+
+ public DefinedElementTerminals(Collection<ObjectTerminal> ts) {
+ super(ts);
+ }
+
+ private IG2DNode findResourceTerminalNode(IG2DNode node, ResourceTerminal rt) {
+ return (IG2DNode) NodeUtil.forChildrenDeep(node, SingleElementNode.class, n -> {
+ Object key = n.getKey();
+ if (rt.getResource().equals(key)) {
+ IG2DNode[] children = n.getSortedNodes();
+ if (children.length > 0)
+ return children[0];
+ return n;
+ }
+ return null;
+ });
+ }
+
+ @Override
+ public AffineTransform getTerminalPosition(IElement e, Terminal t) {
+ if (t instanceof ResourceTerminal) {
+ ResourceTerminal rt = (ResourceTerminal) t;
+ IG2DNode node = e.getHint(DefinedElementHandler.KEY_SG_NODE);
+ if (node != null) {
+ IG2DNode n = findResourceTerminalNode(node, rt);
+ if (n != null) {
+ return n.getTransform();
+ }
+ }
+ }
+
+ ObjectTerminal ti = terminalMap.get(t);
+ if (ti == null)
+ return null;
+ return new AffineTransform(ti.getTransform());
+ }
+
+}
\ No newline at end of file
import org.simantics.structural2.modelingRules.IAttachmentRelationMap;
import org.simantics.structural2.modelingRules.IModelingRules;
import org.simantics.utils.threads.CurrentThread;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
public class RouteGraphUtils {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RouteGraph.class);
public static boolean DEBUG = false;
public static final ILineEndStyle HEAD = new ArrowLineEndStyle("fill 2 1 0");
RouteNode n1 = nodeByData.get(link.first());
RouteNode n2 = nodeByData.get(link.second());
if (n1 == null || n2 == null) {
- System.err.println("Stray connection link found: " + link.toString(graph));
+ LOGGER.warn("Stray connection link found: " + link.toString(graph));
continue;
}
rg.link(n1, n2);
import java.util.EnumSet;
import java.util.Map;
-import javax.vecmath.Vector2d;
-
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.simantics.db.layer0.variable.RVI;
import org.simantics.g2d.diagram.IDiagram;
import org.simantics.g2d.element.ElementClass;
return Double.NaN;
double angrad = Math.toRadians(angle);
- Vector2d forcedAxis = new Vector2d(Math.cos(angrad), Math.sin(angrad));
- Vector2d x = new Vector2d(tr.getScaleX(), tr.getShearX());
- forcedAxis.normalize();
- x.normalize();
- double cosa = forcedAxis.dot(x);
+ Vector2D forcedAxis = new Vector2D(Math.cos(angrad), Math.sin(angrad));
+ Vector2D x = new Vector2D(tr.getScaleX(), tr.getShearX()).normalize();
+ double cosa = forcedAxis.dotProduct(x);
double delta = Math.acos(cosa);
return delta;
}
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;
import org.simantics.ui.fonts.Fonts;
import org.simantics.utils.threads.AWTThread;
-import com.lowagie.text.DocumentException;
-import com.lowagie.text.Element;
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.FontMapper;
-import com.lowagie.text.pdf.PdfFormField;
import com.lowagie.text.pdf.PdfWriter;
-import com.lowagie.text.pdf.TextField;
import gnu.trove.list.array.TIntArrayList;
* TODO:
* o proper support for defining clipping bounds for the text (needed for page templates) (currently through fixedWidth)
* o fix editing xOffset to work with fixed width and multi-line text
- * o
*
* @see Line
* @see TextLayout
private static final long serialVersionUID = 654692698101485672L;
+ public static enum TextFlipping {
+ Disabled,
+ VerticalTextUpwards,
+ VerticalTextDownwards,
+ }
+
/**
* TODO: justify existence for this
*/
protected transient static final int STATE_X_OFFSET_IS_DIRTY = (1 << 7);
protected static final int STATE_ALWAYS_ADD_LISTENERS = (1 << 8);
protected static final int STATE_LISTENERS_ADDED = (1 << 9);
+ protected static final int STATE_AUTOMATIC_TEXT_FLIP_ENABLED = (1 << 10);
+ protected static final int STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN = (1 << 11);
/**
* A combination of all the STATE_ constants defined in this class,
resetCaches();
}
+ public void setAutomaticTextFlipping(TextFlipping type) {
+ switch (type) {
+ case Disabled:
+ clearState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED | STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN);
+ break;
+ case VerticalTextDownwards:
+ setState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED | STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN);
+ break;
+ case VerticalTextUpwards:
+ setState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED);
+ clearState(STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN);
+ break;
+ }
+ }
+
@SyncField({"paddingX", "paddingY"})
public void setPadding(double x, double y) {
this.paddingX = x;
// Safety for not rendering when the scale of this text is too small.
// When the scale is too small it will cause internal exceptions while
// stroking fonts.
- double currentScale = GeometryUtils.getScale(g.getTransform());
+ AffineTransform curTr = g.getTransform();
+ double currentScale = GeometryUtils.getScale(curTr);
//System.out.println("currentScale: " + currentScale);
if (currentScale < 1e-6)
return;
r.setRect(x, y, w, h);
}
+ if (hasState(STATE_AUTOMATIC_TEXT_FLIP_ENABLED)) {
+ boolean needsXFlip;
+ boolean needsYFlip;
+ if (curTr.getScaleX() != 0) {
+ needsXFlip = curTr.getScaleX() < 0.0;
+ needsYFlip = curTr.getScaleY() < 0.0;
+ } else {
+ boolean flipAll = !hasState(STATE_AUTOMATIC_TEXT_FLIP_VERTICAL_DOWN);
+ needsXFlip = (curTr.getShearY() < 0.0) ^ flipAll;
+ needsYFlip = (curTr.getShearX() > 0.0) ^ flipAll;
+ }
+ if (needsXFlip || needsYFlip) {
+ double centerX = r.getWidth()*0.5 + r.getX();
+ double centerY = r.getHeight()*0.5 + r.getY();
+
+ g.translate(centerX, centerY);
+ g.scale(needsXFlip ? -1.0 : 1.0, needsYFlip ? -1.0 : 1.0);
+ g.translate(-centerX, -centerY);
+ }
+ }
+
Rectangle2D textClip = r.getBounds2D();
expandBoundsUnscaled(r);
// PDF
PdfWriter writer = (PdfWriter) g.getRenderingHint(G2DPDFRenderingHints.KEY_PDF_WRITER);
boolean isRenderingPdf = writer != null;
- boolean isPdfField = false;
- String fieldName = null;
- if (writer != null) {
- // TODO: replace this hack with proper text field name field
- fieldName = NodeUtil.getNodeName(this);
- isPdfField = ( fieldName.equals("approved_by") ||
- fieldName.equals("checked_by") ||
- fieldName.equals("designer name") ||
- fieldName.equals("created_by") );
- }
+ /// PDF
Color backgroundColor = hasState(STATE_VALID) ? this.backgroundColor : Color.red;
// RENDER
- if ( !isPdfField ) {
-
+ {
// Fill background if necessary
if (backgroundColor != null) {
g.setColor(backgroundColor);
g.setClip(clip);
- // Caret
-
renderCaret(g);
-
} else {
}
}
- } else {
- // PDF
- // TODO: multiline support
-// try {
- AffineTransform at = g.getTransform();
- float height = writer.getPageSize().getHeight();
- Rectangle2D rr = textClip;
- // Point2D pt1 = new Point2D.Double(rr.getX(), rr.getY()+rr.getHeight());
- // Point2D pt2 = new Point2D.Double(rr.getX()+rr.getWidth(), rr.getY());
- Point2D pt1 = new Point2D.Double(0, 0);
- Point2D pt2 = new Point2D.Double(47.f/*+rr.getWidth()*/, -rr.getHeight());
- pt1 = at.transform(pt1, pt1);
- pt2 = at.transform(pt2, pt2);
- Rectangle rectangle = new Rectangle(
- (float) pt1.getX(),
- height-(float) pt1.getY(),
- (float) pt2.getX(),
- height-(float) pt2.getY());
-
- FontMapper mapper = (FontMapper) g.getRenderingHint(G2DPDFRenderingHints.KEY_PDF_FONTMAPPER);
-// FontMetrics fm = g.getFontMetrics(font);
-
- // TODO Oikea leveys
- // TODO Uniikki nimi
- /*
- PdfFormField field = PdfFormField.createTextField(writer, false, false, 20);
- field.setFieldName(this.getId().toString());
- field.setWidget(rectangle, PdfAnnotation.HIGHLIGHT_NONE);
- field.setQuadding(PdfFormField.Q_RIGHT);
- field.setFieldFlags(PdfFormField.FF_READ_ONLY);
- field.setRotate(90);
- writer.addAnnotation(field);
- */
-
-
- // Signature Field
- /*
- if (text==null) {
- PdfFormField field = PdfFormField.createSignature(writer);
- field.setWidget(rectangle, PdfAnnotation.HIGHLIGHT_NONE);
- field.setFieldName(fieldName);
- field.setQuadding(PdfFormField.Q_LEFT);
- field.setFlags(PdfAnnotation.FLAGS_PRINT);
- //field.setFieldFlags(PdfFormField.FF_READ_ONLY)
- field.setFieldFlags(PdfFormField.FF_EDIT);
- field.setPage();
- field.setMKBackgroundColor( backgroundColor!=null?Color.WHITE:backgroundColor );
- PdfAppearance tp = PdfAppearance.createAppearance(writer, 72, 48);
- tp.rectangle(rectangle);
- tp.stroke();
- field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
- writer.addAnnotation(field);
- } else */
- {
- // Text Field
- try {
- TextField textField = new TextField(writer, rectangle, fieldName);
- textField.setFieldName(fieldName);
- textField.setFont(mapper.awtToPdf(font));
- textField.setBorderStyle(0);
- //textField.setAlignment(Element.ALIGN_LEFT);
- textField.setAlignment(Element.ALIGN_BOTTOM);
- textField.setRotation(90);
- textField.setOptions(TextField.EDIT|TextField.DO_NOT_SPELL_CHECK);
- if ( text!=null ) {
- textField.setText(text);
- }
- if ( color!=null ) {
- textField.setTextColor(color);
- }
- textField.setBackgroundColor( backgroundColor!=null?Color.WHITE:backgroundColor );
- PdfFormField field = textField.getTextField();
- writer.addAnnotation(field);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (DocumentException e) {
- e.printStackTrace();
- }
- }
-
-// } catch (IOException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// } catch (DocumentException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
}
- /// PDF
g.setClip(clipSave);
import java.util.ArrayList;
import java.util.Collection;
-import javax.vecmath.Tuple2d;
-import javax.vecmath.Vector2d;
-
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
String commonLabel = scheme.generateLabel(graph, diagram);
// Create flags and connect both disconnected ends to them.
- Vector2d pos1, pos2;
+ Point2D pos1, pos2;
double theta;
double flagDist = 3.0;
if(isHorizontal) {
theta = 0.0;
- pos1 = new Vector2d(isectX-flagDist, isectY);
- pos2 = new Vector2d(isectX+flagDist, isectY);
+ pos1 = new Point2D.Double(isectX-flagDist, isectY);
+ pos2 = new Point2D.Double(isectX+flagDist, isectY);
}
else {
theta = Math.PI*0.5;
- pos1 = new Vector2d(isectX, isectY-flagDist);
- pos2 = new Vector2d(isectX, isectY+flagDist);
+ pos1 = new Point2D.Double(isectX, isectY-flagDist);
+ pos2 = new Point2D.Double(isectX, isectY+flagDist);
}
// Chooses flag directions
}
}
- private AffineTransform getFlagTransform(Tuple2d pos, double theta) {
- AffineTransform at = AffineTransform.getTranslateInstance(pos.x, pos.y);
+ private AffineTransform getFlagTransform(Point2D pos, double theta) {
+ AffineTransform at = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
at.rotate(theta);
return at;
}
import java.util.HashSet;
import java.util.Set;
-import javax.vecmath.Tuple2d;
-import javax.vecmath.Vector2d;
-
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
// Calculate split position and edge line nearest intersection point
// ab = normalize( vec(a -> b) )
// ap = vec(a -> split pos)
- Vector2d ab = new Vector2d(nearestEdge.getX2() - nearestEdge.getX1(), nearestEdge.getY2() - nearestEdge.getY1());
- Vector2d ap = new Vector2d(splitCanvasPos.getX() - nearestEdge.getX1(), splitCanvasPos.getY() - nearestEdge.getY1());
- double theta = Math.atan2(ab.y, ab.x);
- ab.normalize();
+ Vector2D a = new Vector2D(nearestEdge.getX1(), nearestEdge.getY1());
+ Vector2D ab = new Vector2D(nearestEdge.getX2() - nearestEdge.getX1(), nearestEdge.getY2() - nearestEdge.getY1());
+ Vector2D ap = new Vector2D(splitCanvasPos.getX() - nearestEdge.getX1(), splitCanvasPos.getY() - nearestEdge.getY1());
+ double theta = Math.atan2(ab.getY(), ab.getX());
+ ab = ab.normalize();
// intersection = a + ab*(ap.ab)
- Vector2d intersection = new Vector2d(ab);
- intersection.scale(ap.dot(ab));
- intersection.add(new Vector2d(nearestEdge.getX1(), nearestEdge.getY1()));
+ Vector2D intersection = a.add( ab.scalarMultiply(ap.dotProduct(ab)) );
// Offset flag positions from the intersection point.
- Vector2d pos1 = new Vector2d(intersection);
- Vector2d pos2 = new Vector2d(intersection);
-
// TODO: improve logic for flag positioning, flags just move on the nearest line without boundaries
- ab.normalize();
- ab.scale(5);
- pos2.add(ab);
- ab.negate();
- pos1.add(ab);
+ Vector2D pos1 = intersection.subtract(5, ab);
+ Vector2D pos2 = intersection.add(5, ab);
FlagLabelingScheme scheme = DiagramFlagPreferences.getActiveFlagLabelingScheme(graph);
String commonLabel = scheme.generateLabel(graph, diagram);
FlagUtil.join(graph, flag1, flag2);
}
- private AffineTransform getFlagTransform(Tuple2d pos, double theta) {
- AffineTransform at = AffineTransform.getTranslateInstance(pos.x, pos.y);
+ private AffineTransform getFlagTransform(Vector2D pos, double theta) {
+ AffineTransform at = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
at.rotate(theta);
return at;
}
* A key for storing the current selection within the currently active
* project for copy/paste implementation.
*/
- private static final Key KEY_DIAGRAM_SELECTION = DiagramSelectionRepresentation.KEY_DIAGRAM_SELECTION;
+ private static final Key KEY_DIAGRAM_SELECTION = DiagramSelectionRepresentation.KEY_DIAGRAM_SELECTION;
private static final boolean DEBUG = false;
private static final boolean DEBUG_SELECTION_UPDATE = false;
public static final int COPY_GHOSTING_PAINT_PRIORITY = 600;
- private static final int HIGHLIGHT_PAINT_PRIORITY = 500;
+ protected static final int HIGHLIGHT_PAINT_PRIORITY = 500;
@Dependency
- private Selection sel;
+ protected Selection sel;
@Dependency
- private MouseUtil mouseUtil;
+ protected MouseUtil mouseUtil;
protected final IStatusLineManager statusLine;
protected final CopyPasteStrategy strategy;
*/
protected boolean hasFocus = false;
- private AbstractCanvasParticipant highlightMode = null;
+ protected AbstractCanvasParticipant highlightMode = null;
private IProject observedProject = null;
/**
return DiagramSelection.EMPTY;
}
- private DiagramSelection getProjectSelection() {
+ protected DiagramSelection getProjectSelection() {
IProject p = peekProject();
if (p == null)
return DiagramSelection.EMPTY;
return ds != null ? ds : DiagramSelection.EMPTY;
}
- void setDiagramSelection(DiagramSelection selection) {
+ protected void setDiagramSelection(DiagramSelection selection) {
setProjectSelection(selection);
strategy.copyToClipboard(selection);
}
- void setProjectSelection(DiagramSelection selection) {
+ protected void setProjectSelection(DiagramSelection selection) {
assert selection != null;
IProject p = getProject();
if (p == null)
p.setHint(KEY_DIAGRAM_SELECTION, selection);
}
- private void removeProjectSelection() {
+ protected void removeProjectSelection() {
setProjectSelection(DiagramSelection.EMPTY);
removeHighlight();
clearSG();
return false;
}
- boolean initiateCopy(boolean cut) {
+ protected boolean initiateCopy(boolean cut) {
//System.out.println("INITIATING COPY");
int selectionId = 0;
message(null);
return false;
}
-
+
TimeLogger.resetTimeAndLog(getClass(), "paste");
ElementObjectAssortment ea = ds.getAssortment();
}
}
- private String fixAssortment(ElementAssortment ea, boolean cut) {
+ protected String fixAssortment(ElementAssortment ea, boolean cut) {
Topology diagramTopology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class);
List<Connection> conns = new ArrayList<Connection>();
* @param ea
* @return
*/
- private void pruneAssortment(ElementAssortment ea, boolean cut) {
+ protected void pruneAssortment(ElementAssortment ea, boolean cut) {
// Edges and branch points are never copied as such.
// They are always included as parts of copied connections.
// Edges can never be transformed or modified in any way as such,
* @param e
* @return
*/
- private static boolean isConnectionOrEdge(IElement e) {
+ protected static boolean isConnectionOrEdge(IElement e) {
ElementClass ec = e.getElementClass();
return ec.containsClass(ConnectionHandler.class)|| ec.containsClass(BendsHandler.class);
}
* @param e
* @return
*/
- private static boolean isMoveable(IElement e) {
+ protected static boolean isMoveable(IElement e) {
ElementClass ec = e.getElementClass();
return ec.containsClass(Move.class) && ec.containsClass(Transform.class);
}
* @return <code>null</code> if a point of reference cannot be determined
* for the specified selection.
*/
- private Point2D getCopyStartPos(Set<IElement> ss) {
+ protected Point2D getCopyStartPos(Set<IElement> ss) {
// MouseInfo mi = mouseUtil.getMouseInfo(0);
// if (mi != null) {
// return (Point2D) mi.canvasPosition.clone();
return ghostNode.addNode(id, clazz);
}
- private boolean hasHighlight() {
+ protected boolean hasHighlight() {
return highlightMode != null;
}
- private void removeHighlight() {
+ protected void removeHighlight() {
if (isRemoved())
return;
assert getContext().getThreadAccess().currentThreadAccess();
return (e.stateMask & MouseEvent.CTRL_MASK) != 0;
}
- void selectedMessage(DiagramSelection ds) {
+ protected void selectedMessage(DiagramSelection ds) {
int size = ds.getOriginalElements().size();
StringBuilder sb = new StringBuilder();
if (size == 0) {
message(sb.toString());
}
- void message(final String message) {
+ protected void message(final String message) {
if (statusLine == null)
return;
swtExec(new Runnable() {
});
}
- void error(final String message) {
+ protected void error(final String message) {
if (statusLine == null)
return;
swtExec(new Runnable() {
});
}
- void swtExec(Runnable r) {
+ protected void swtExec(Runnable r) {
ThreadUtils.asyncExec(SWTThread.getThreadAccess(Display.getDefault()), r);
}
graph.claim(resource, L0X.ObtainsProperty1, null, template);
}
}
-
+
}
});
}
package org.simantics.diagram.handler;
import static org.simantics.diagram.handler.Paster.ComposedCutProcedure.compose;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
+import java.util.function.BiFunction;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.structural2.modelingRules.CPTerminal;
import org.simantics.structural2.modelingRules.ConnectionJudgement;
import org.simantics.structural2.modelingRules.IConnectionPoint;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.simantics.utils.datastructures.map.Tuple;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
/**
* @author Tuukka Lehtonen
*/
return noParentElementReturnValue;
}
- private void cut() throws Exception {
+ protected void cut() throws Exception {
final GraphLayerManager glm = targetContext.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER);
final THashSet<Resource> cutElements = new THashSet<Resource>();
* Diagram mapping will have problems and potentially break the
* configuration if the type is not the same as in the source.
*/
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> statementAdvisor =
- new BinaryFunction<StatementEvaluation, ReadGraph, Statement>() {
+ BiFunction<ReadGraph, Statement, StatementEvaluation> statementAdvisor =
+ new BiFunction<ReadGraph, Statement, StatementEvaluation>() {
@Override
- public StatementEvaluation call(ReadGraph graph, Statement stm) {
+ public StatementEvaluation apply(ReadGraph graph, Statement stm) {
if (DIA.HasFlagType.equals(stm.getPredicate()))
return StatementEvaluation.INCLUDE;
return StatementEvaluation.USE_DEFAULT;
}
};
- private void copy() throws Exception {
+ protected void copy() throws Exception {
nodeMap = new NodeMap();
CommonDBUtils.selectClusterSet(graph, targetDiagram);
public NodeMap getNodeMap() {
return nodeMap;
}
-
+
+ protected PasteOperation getOperation() {
+ return op;
+ }
}
final boolean expanded = grp.getExpanded();
final boolean visible = grp.getVisible();
final boolean filterChanged = !objectEquals(filter, lastFilter);
+ final ISymbolGroup symbolGroup = (ISymbolGroup) grp.getData(SymbolLibraryKeys.KEY_GROUP);
+ final boolean filterMatchesGroup = filter != null && filter.select(viewer, null, symbolGroup);
// Find out how much data would be shown with the new filter.
- viewer.setFilter(filter);
+ viewer.setFilter(filterMatchesGroup ? null : filter);
Object[] elements = viewer.getFilteredElements();
- ISymbolGroup symbolGroup = (ISymbolGroup) grp.getData(SymbolLibraryKeys.KEY_GROUP);
- boolean filterMatchesGroup = filter != null && filter.select(viewer, null, symbolGroup);
boolean shouldBeVisible = !groupFiltered && (elements.length > 0 || filterMatchesGroup);
boolean shouldBeExpanded = shouldBeVisible && (filter != null || userExpanded);
-// System.out.format("%40s: visible/should be = %5s %5s, expanded/user expanded/should be = %5s %5s %5s\n",
+// System.out.format("%40s: filterMatchesGroup(%s) = %s, visible/should be = %5s %5s, expanded/user expanded/should be = %5s %5s %5s\n",
// grp.getText(),
+// symbolGroup.getName(),
+// String.valueOf(filterMatchesGroup),
// String.valueOf(visible),
// String.valueOf(shouldBeVisible),
// String.valueOf(expanded),
import java.util.Map;
import java.util.Set;
+import java.util.function.BiFunction;
import org.simantics.databoard.Bindings;
import org.simantics.databoard.binding.Binding;
import org.simantics.graph.db.TransferableGraphs;
import org.simantics.graph.representation.TransferableGraph1;
import org.simantics.layer0.Layer0;
-import org.simantics.utils.datastructures.BinaryFunction;
/**
* This class contains utility methods for the basic cut/copy operations
* @return the copied resource
* @throws DatabaseException
*/
- public static Resource copy(WriteGraph graph, Resource source, BinaryFunction<Boolean, ReadGraph, Statement> advisor) throws DatabaseException {
+ public static Resource copy(WriteGraph graph, Resource source, BiFunction<ReadGraph, Statement, Boolean> advisor) throws DatabaseException {
return copy(graph, source, 0, advisor, new THashMap<Object, Object>());
}
* @return
* @throws DatabaseException
*/
- public static Resource copy(WriteGraph graph, Resource source, BinaryFunction<Boolean, ReadGraph, Statement> advisor, Map<Object, Object> copyMap) throws DatabaseException {
+ public static Resource copy(WriteGraph graph, Resource source, BiFunction<ReadGraph, Statement, Boolean> advisor, Map<Object, Object> copyMap) throws DatabaseException {
return copy(graph, source, 0, advisor, copyMap);
}
- private static Resource copy(WriteGraph graph, Resource source, int level, BinaryFunction<Boolean, ReadGraph, Statement> advisor, Map<Object, Object> copyMap) throws DatabaseException {
+ private static Resource copy(WriteGraph graph, Resource source, int level, BiFunction<ReadGraph, Statement, Boolean> advisor, Map<Object, Object> copyMap) throws DatabaseException {
if (DEBUG_COPY)
System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")");
}
} else {
if (advisor != null) {
- Boolean result = advisor.call(graph, stm);
+ Boolean result = advisor.apply(graph, stm);
if (Boolean.TRUE.equals(result)) {
// Don't clone the object, just add relation to the same object.
if (inverse != null)
* @throws DatabaseException
*/
public static Resource copy2(WriteGraph graph, Resource source,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor) throws DatabaseException {
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor) throws DatabaseException {
return copy2(graph, source, 0, advisor, new THashMap<Object, Object>());
}
* @throws DatabaseException
*/
public static Resource copy2(WriteGraph graph, Resource source,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor, Map<Object, Object> copyMap)
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
throws DatabaseException {
return copy2(graph, source, 0, advisor, copyMap);
}
private static Resource copy2(final WriteGraph graph, final Resource source, final int level,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor, Map<Object, Object> copyMap)
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
throws DatabaseException {
if (DEBUG_COPY)
System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")");
* @throws DatabaseException
*/
public static Resource copy3(WriteGraph graph, Resource source, Resource model,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor) throws DatabaseException {
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor) throws DatabaseException {
String modelURI = graph.getURI(model);
return copy3(graph, modelURI, source, 0, advisor, new THashMap<Object, Object>());
}
* @throws DatabaseException
*/
public static Resource copy3(WriteGraph graph, Resource source, Resource model,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor, Map<Object, Object> copyMap) throws DatabaseException {
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap) throws DatabaseException {
String modelURI = graph.getURI(model);
return copy3(graph, modelURI, source, 0, advisor, copyMap);
}
private static Resource copy3(WriteGraph graph, String modelURI, Resource source, int level,
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> advisor, Map<Object, Object> copyMap)
+ BiFunction<ReadGraph, Statement, StatementEvaluation> advisor, Map<Object, Object> copyMap)
throws DatabaseException {
if (DEBUG_COPY)
System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")");
return copy;
}
- protected static StatementEvaluation evaluate(ReadGraph graph, Statement stm, BinaryFunction<StatementEvaluation, ReadGraph, Statement> tester) {
+ protected static StatementEvaluation evaluate(ReadGraph graph, Statement stm, BiFunction<ReadGraph, Statement, StatementEvaluation> tester) {
if (tester == null)
return StatementEvaluation.USE_DEFAULT;
- return tester.call(graph, stm);
+ return tester.apply(graph, stm);
}
/**
org.simantics.scenegraph.ontology;bundle-version="1.0.0",
org.simantics.viewpoint.ontology;bundle-version="1.0.0",
org.simantics.selectionview.ontology;bundle-version="1.1.0",
- org.simantics.graphfile.ontology;bundle-version="0.1.0"
+ org.simantics.graphfile.ontology;bundle-version="0.1.0",
+ org.simantics.action.ontology;bundle-version="1.1.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.simantics.document
SG = <http://www.simantics.org/Scenegraph-1.1>
SEL = <http://www.simantics.org/SelectionView-1.2>
GF = <http://www.simantics.org/GraphFile-0.1>
+ACT = <http://www.simantics.org/Action-1.1>
DOC = <http://www.simantics.org/Document-1.2> : L0.Ontology
@L0.new
DOC.DocumentLibrary <T L0.Library
+
+DOC.Actions : L0.Library
+
+DOC.Actions.ImportFileDocument : ACT.Action
\ No newline at end of file
public class DocumentResource {
+ public final Resource Actions;
+ public final Resource Actions_ImportFileDocument;
public final Resource Document;
public final Resource DocumentLibrary;
public final Resource DocumentSettings;
public final Resource documentSettings_Inverse;
public static class URIs {
+ public static final String Actions = "http://www.simantics.org/Document-1.2/Actions";
+ public static final String Actions_ImportFileDocument = "http://www.simantics.org/Document-1.2/Actions/ImportFileDocument";
public static final String Document = "http://www.simantics.org/Document-1.2/Document";
public static final String DocumentLibrary = "http://www.simantics.org/Document-1.2/DocumentLibrary";
public static final String DocumentSettings = "http://www.simantics.org/Document-1.2/DocumentSettings";
}
public DocumentResource(ReadGraph graph) {
+ Actions = getResourceOrNull(graph, URIs.Actions);
+ Actions_ImportFileDocument = getResourceOrNull(graph, URIs.Actions_ImportFileDocument);
Document = getResourceOrNull(graph, URIs.Document);
DocumentLibrary = getResourceOrNull(graph, URIs.DocumentLibrary);
DocumentSettings = getResourceOrNull(graph, URIs.DocumentSettings);
public interface ITreeTableCell extends ITableCell {
int getParent();
+
+ Object getData();
+
+ boolean isEditable();
+
}
package org.simantics.document.server.io;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
else
return Collections.<IListItem>emptyList();
}
+
+ @SuppressWarnings("unchecked")
+ public static Collection<ITreeTableCell> getTreeTableCell(IJSONObject object) {
+ try {
+ Object treeTableCells = object.getValue("tableCells");
+ if (treeTableCells instanceof String) {
+ String tableCellsS = (String) treeTableCells;
+ if (tableCellsS.length() == 0)
+ return Collections.emptyList();
+ }
+ if (treeTableCells != null) {
+ return (List<ITreeTableCell>) treeTableCells;
+ } else {
+ return Collections.emptyList();
+ }
+ } catch (ClassCastException e) {
+ e.printStackTrace();
+ }
+ return Collections.emptyList();
+ }
+
+ public static final boolean equalObjects(Object oldValue, Object newValue) {
+ if (newValue != null) {
+ if (newValue.getClass().isArray()) {
+ return arrayEquals(newValue, oldValue);
+ } else {
+ return newValue.equals(oldValue);
+ }
+ } else
+ return oldValue == null;
+ }
+
+
+ /**
+ * @param av1 an array (guaranteed)
+ * @param av2 any object
+ * @return <code>true</code> if the two arrays are equal
+ */
+ private static final boolean arrayEquals(Object av1, Object av2) {
+ if (av2 == null)
+ return false;
+ Class<?> c1 = av1.getClass().getComponentType();
+ Class<?> c2 = av2.getClass().getComponentType();
+ if (c2 == null || !c1.equals(c2))
+ return false;
+ boolean p1 = c1.isPrimitive();
+ boolean p2 = c2.isPrimitive();
+ if (p1 != p2)
+ return false;
+ if (!p1)
+ return Arrays.equals((Object[]) av1, (Object[]) av2);
+ if (boolean.class.equals(c1))
+ return Arrays.equals((boolean[]) av1, (boolean[]) av2);
+ else if (byte.class.equals(c1))
+ return Arrays.equals((byte[]) av1, (byte[]) av2);
+ else if (int.class.equals(c1))
+ return Arrays.equals((int[]) av1, (int[]) av2);
+ else if (long.class.equals(c1))
+ return Arrays.equals((long[]) av1, (long[]) av2);
+ else if (float.class.equals(c1))
+ return Arrays.equals((float[]) av1, (float[]) av2);
+ else if (double.class.equals(c1))
+ return Arrays.equals((double[]) av1, (double[]) av2);
+ throw new RuntimeException("Unsupported objects for equality testing ." + av1 + " vs. " + av2);
+
+ }
+
+
}
importJava "org.simantics.document.server.io.IFont" where
data IFont
+
+ @JavaName getFamily
+ fontFamily :: IFont -> <Proc> Maybe String
+ @JavaName getStyle
+ fontStyle :: IFont -> <Proc> Maybe String
+ @JavaName getHeight
+ fontHeight :: IFont -> <Proc> Integer
importJava "org.simantics.document.server.io.IColor" where
data IColor
Bundle-Vendor: Semantum Oy
Require-Bundle: org.simantics.layer0,
org.simantics.views.ontology;bundle-version="1.1.0",
+ org.simantics.views.text.ontology;bundle-version="1.0.0",
org.simantics.modeling.ontology;bundle-version="1.1.0",
org.simantics.scenegraph.ontology;bundle-version="1.0.0",
org.simantics.document.ontology;bundle-version="1.1.0",
L0 = <http://www.simantics.org/Layer0-1.1>
VIEWS = <http://www.simantics.org/Views-1.2>
+TEXTVIEWS = <http://www.simantics.org/TextViews-1.0>
SG = <http://www.simantics.org/Scenegraph-1.1>
DOC = <http://www.simantics.org/Document-1.2>
ACT = <http://www.simantics.org/Action-1.1>
@L0.list
_ : VIEWS.Composite
VIEWS.Composite.layout _ : VIEWS.RowLayout
- //VIEWS.RowLayout.type VIEWS.Control.Style.Constant.Horizontal
- //VIEWS.RowLayout.spacing 0
- //VIEWS.RowLayout.justify true
- //VIEWS.RowLayout.pack true
- //VIEWS.RowLayout.wrap true
VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData
VIEWS.GridLayout.GridData.horizontalGrab true
SG.Node.children _ : L0.List
VIEWS.Composite.layout _ : VIEWS.GridLayout
SG.Node.children _ : L0.List
@L0.list
- UI.WikitextContribution.View.Text : VIEWS.StyledText
+ UI.WikitextContribution.View.Text : TEXTVIEWS.MarkupSourceViewer
@VIEWS.Control.style4 VIEWS.Control.Style.Constant.Multi VIEWS.Control.Style.Constant.Border VIEWS.Control.Style.Constant.VScroll VIEWS.Control.Style.Constant.HScroll
VIEWS.TextContainer.text UI.Functions.selectedDocumentPart : L0.Function
L0.HasValueType "String"
VIEWS.SashForm.orientation VIEWS.SashForm.Vertical
SG.Node.children _ : L0.List
@L0.list
-// UI.Scroll : VIEWS.ScrolledComposite
- // VIEWS.Control.layoutData
- // _ : VIEWS.GridLayout.GridData
- // VIEWS.GridLayout.GridData.horizontalGrab true
- // VIEWS.GridLayout.GridData.verticalGrab true
- // SG.Node.children _ : L0.List
- // @L0.list
UI.Browser : VIEWS.Browser
VIEWS.Control.layoutData
_ : VIEWS.GridLayout.GridData
Bundle-Vendor: Semantum Oy
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
+ org.simantics.views;bundle-version="1.1.0",
org.simantics.views.swt;bundle-version="1.0.0",
org.simantics.document.ontology;bundle-version="1.0.0",
org.simantics.document.ui.ontology;bundle-version="1.0.0",
org.simantics.modeling.ontology;bundle-version="1.1.0",
org.simantics.scenegraph.ontology;bundle-version="1.0.0",
org.simantics.document;bundle-version="1.0.0",
- org.eclipse.mylyn.wikitext.mediawiki.core;bundle-version="1.5.2",
- org.eclipse.mylyn.wikitext.core;bundle-version="1.5.1",
org.simantics.wiki.ui;bundle-version="1.1.0",
org.simantics.browsing.ui;bundle-version="1.1.0",
org.simantics.selectionview;bundle-version="1.0.0",
- org.simantics.views;bundle-version="1.1.0",
org.simantics.utils.thread.swt;bundle-version="1.1.0",
org.simantics.browsing.ui.model;bundle-version="1.0.0";visibility:=reexport,
org.simantics.graphfile;bundle-version="0.1.0",
org.simantics.annotation.ontology;bundle-version="1.0.0",
org.simantics.annotation.ui;bundle-version="1.0.0",
org.eclipse.ui.editors;bundle-version="3.9.0",
- org.eclipse.jface.text
+ org.eclipse.jface.text,
+ org.slf4j.api;bundle-version="1.7.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.simantics.document.ui,
exportDocument :: Resource -> String -> <Proc> ()
documentsFolders :: Model -> <ReadGraph> [Resource]
-documentsFolders model = recurse DOCUMENT.DocumentLibrary (toResource model)
+documentsFolders model = recurse DOCUMENT.DocumentLibrary model
where
recurse t r = do
- cs = resourceChildrenOf r
+ cs = children r
libraries = filter isLibrary cs
libraryGrp = filter (not . isLibrary) cs
libraries + concatMap (recurse t) libraryGrp
isLibrary r = isInstanceOf r DOCUMENT.DocumentLibrary
documents :: Model -> <ReadGraph> [Resource]
-documents model = recurse DOCUMENT.Document (toResource model)
+documents model = recurse DOCUMENT.Document model
where
recurse t r = do
- cs = resourceChildrenOf r
+ cs = children r
documents = filter isDocument cs
documentFolder = filter (not . isDocument) cs
documents + concatMap (recurse t) documentFolder
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.document.AddDocumentAction;
import org.simantics.document.DocumentResource;
import org.simantics.layer0.Layer0;
import org.simantics.utils.datastructures.Callback;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
import org.simantics.db.exception.ServiceException;
+import org.simantics.document.AddDocumentAction;
import org.simantics.document.DocumentResource;
import org.simantics.document.ui.dialogs.UrlDetailDialog;
import org.simantics.layer0.Layer0;
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.document.FileDocumentUtil;
import org.simantics.document.ui.Activator;
-import org.simantics.document.ui.graphfile.FileDocumentUtil;
import org.simantics.graphfile.util.GraphFileUtil;
/**
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.document.FileDocumentUtil;
import org.simantics.document.ui.Activator;
-import org.simantics.document.ui.graphfile.FileDocumentUtil;
/**
* Action for importing files as documents.
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.document.AddDocumentAction;
+import org.simantics.document.FileDocumentUtil;
import org.simantics.document.ui.dialogs.FileDetailDialog;
-import org.simantics.document.ui.graphfile.FileDocumentUtil;
import org.simantics.layer0.Layer0;
import org.simantics.utils.datastructures.Callback;
import org.simantics.utils.ui.ExceptionUtils;
/*******************************************************************************
- * Copyright (c) 2012 Association for Decentralized Information Management in
+ * Copyright (c) 2012, 2017 Association for Decentralized Information Management in
* Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - (#7066) introducing logger & refactoring
*******************************************************************************/
package org.simantics.document.ui.function;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.request.UnaryRead;
import org.simantics.db.common.request.WriteRequest;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.common.utils.RequestUtil;
import org.simantics.db.exception.DatabaseException;
import org.simantics.ui.workbench.action.DefaultActions;
import org.simantics.utils.threads.SWTThread;
import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class All {
+ private static final Logger LOGGER = LoggerFactory.getLogger(All.class);
+
private static boolean createDocument(WriteGraph graph, Resource resource, Resource model) throws DatabaseException {
Layer0 L0 = Layer0.getInstance(graph);
if(document == null) return;
RemoverUtil.remove(graph, document);
+ graph.markUndoPoint();
}
@Override
public void perform(WriteGraph graph) throws DatabaseException {
-
Variable selection = resolveEditSelection(graph, context, "..../Scroll/Browser#edited");
- if (selection != null)
+ if (selection != null) {
selection.setValue(graph, (String)value, Bindings.STRING);
- else {
- System.err.println("no selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);
+ graph.markUndoPoint();
+ } else {
+ LOGGER.error("No selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);
}
}
String editorId = CSSEditor.EDITOR_ID;
RVI rvi = null;
- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-
- @Override
- public void run() {
-
- try {
- WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));
- } catch (PartInitException e) {
- Logger.defaultLogError(e);
- }
-
+ PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
+ try {
+ WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));
+ } catch (PartInitException e) {
+ LOGGER.error("Failed to open CSS editor for root " + root, e);
}
-
});
}
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.simantics.db.Resource;
-import org.simantics.document.ui.graphfile.FileDocumentUtil;
+import org.simantics.document.FileDocumentUtil;
public abstract class FileDocumentImportWizard extends Wizard{
org.simantics.wiki.ui;bundle-version="1.1.0",
org.simantics.export.core;bundle-version="1.0.0",
org.simantics.utils.ui;bundle-version="1.1.0",
- org.simantics.image2.ontology;bundle-version="1.2.0"
+ org.simantics.image2.ontology;bundle-version="1.2.0",
+ org.simantics.graphfile.ontology;bundle-version="0.1.0",
+ org.simantics.graphfile;bundle-version="0.1.0"
Export-Package: org.simantics.document,
org.simantics.document.export,
org.simantics.document.function,
public class Activator implements BundleActivator {
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.simantics.document"; //$NON-NLS-1$
+
private static BundleContext context;
static BundleContext getContext() {
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.document;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+
+/**
+ * Abstract base class for adding documents.
+ *
+ * If import target is an document, a new version of a document is created.
+ *
+ * Document version creation has two modes:
+ * FLAT: new version is added to the same library as the old document.
+ * TREE: new version replaces the old document in the library, and old document is moved under the new document.
+ *
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public abstract class AddDocumentAction implements ActionFactory {
+
+ private Resource relation;
+
+ public AddDocumentAction(ReadGraph graph, String relationUri) throws DatabaseException {
+ relation = graph.getResource(relationUri);
+ }
+
+
+ protected Resource getRelation() {
+ return relation;
+ }
+
+ protected void linkDocument(WriteGraph graph, Resource target, Resource newDocument) throws DatabaseException{
+ DocumentResource doc = DocumentResource.getInstance(graph);
+
+ if (graph.isInstanceOf(target, doc.Document)) {
+ // adding a new revision
+ DocumentVersionUtils.createNewVersion(graph, target, newDocument, relation);
+
+
+ } else {
+ graph.claim(target, relation, newDocument);
+ FileDocumentUtil.createUniqueName(graph, newDocument);
+ }
+ }
+
+}
import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.common.request.WriteResultRequest;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
}
}
- public void print(RequestProcessor processor, Resource res, String wiki, String css, DocumentSettings settings, final PdfWriter writer, final Document document) throws DocumentException {
- try {
- Exportable exp = processor.syncRequest(new UniqueRead<Exportable>() {
-
- @Override
- public Exportable perform(ReadGraph graph) throws DatabaseException {
- return new Exportable(graph, res, wiki, css, settings, true);
- }
-
- });
- exp.export(document, writer);
- } catch (DocumentException e) {
- Logger.defaultLogError(e);
- } catch (DatabaseException e) {
- Logger.defaultLogError(e);
- }
+ public int print(RequestProcessor processor, Resource res, String wiki, String css, DocumentSettings settings, final PdfWriter writer, final Document document)
+ throws DocumentException, DatabaseException {
+ Exportable exp = processor.syncRequest(new UniqueRead<Exportable>() {
+ @Override
+ public Exportable perform(ReadGraph graph) throws DatabaseException {
+ return new Exportable(graph, res, wiki, css, settings, true);
+ }
+ });
+ return exp.export(document, writer);
}
public static String indexRootPath(ReadGraph graph, Variable selection) throws DatabaseException {
--- /dev/null
+package org.simantics.document;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.document.DocumentResource;
+import org.simantics.layer0.Layer0;
+/**
+ * Util class for managing document versions
+ *
+ * Document version history mode is searched with relations:
+ * 1. l0.PartOf
+ * 2. l0.IsOwnedBy
+ * 3. l0.IsDependencyOf
+ *
+ * If library is not found, history mode is assumed to be flat.
+ *
+ * In order to have working tree history, the library must contain proper configuration for relations:
+ * doc.HasLibraryRelation
+ * doc.HasVersionType
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class DocumentVersionUtils {
+
+ public enum VersionMode{FLAT,TREE};
+
+
+ /**
+ * Adds a new document version.
+ *
+ * Expects that newDocument is not part of document version chain, and oldDocument does not have newer version.
+ *
+ * @param graph
+ * @param oldDocument
+ * @param newDocument
+ * @param relation
+ * @throws DatabaseException
+ */
+ public static void createNewVersion(WriteGraph graph, Resource oldDocument, Resource newDocument, Resource relation) throws DatabaseException{
+ DocumentResource doc = DocumentResource.getInstance(graph);
+ if (graph.hasStatement(oldDocument, doc.HasNewerVersion))
+ throw new DatabaseException("Document " + NameUtils.getSafeName(graph, oldDocument) +" has already new version");
+
+ Resource inverse = graph.getInverse(relation);
+ Resource lib = graph.getSingleObject(oldDocument, inverse);
+ String modeString = graph.getPossibleRelatedValue(lib, doc.HasVersionType);
+ VersionMode mode = VersionMode.FLAT;
+ if (modeString != null)
+ mode = VersionMode.valueOf(modeString);
+
+ graph.claim(oldDocument, doc.HasNewerVersion, newDocument);
+ graph.claim(lib, relation, newDocument);
+
+ if (mode == VersionMode.TREE) {
+ graph.deny(lib,relation,oldDocument);
+ graph.claim(newDocument,relation,oldDocument);
+ }
+ FileDocumentUtil.createUniqueName(graph, newDocument);
+ }
+
+ /**
+ * Sets document version relationship between two documents.
+ *
+ * If the documents are already part of the same version chain this method does nothing.
+ *
+ * If documents are already set to some version chain with given relation, this method replaces the exiting links.
+ *
+ * @param graph
+ * @param document1
+ * @param document2
+ * @param versionRel
+ * @throws DatabaseException
+ */
+ public static void setVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException {
+ DocumentResource doc = DocumentResource.getInstance(graph);
+ // document type must match
+ if (!graph.getSingleType(document2, doc.Document).equals(graph.getSingleType(document1, doc.Document)))
+ return;
+ if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion)))
+ throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel));
+
+ Resource versionRelInv = graph.getInverse(versionRel);
+ // toSet must not be part of the document's version history
+ Resource r = document1;
+ while (r != null) {
+ if (r.equals(document2))
+ return;
+ r = graph.getPossibleObject(r, versionRel);
+ }
+
+ r = document2;
+ while (r != null) {
+ if (r.equals(document1))
+ return;
+ r = graph.getPossibleObject(r, versionRel);
+ }
+ // At the moment document revision history is linear (no branching).
+ Resource document1Ver = graph.getPossibleObject(document1, versionRel);
+ if (document1Ver != null)
+ unsetVersion(graph, document1, document1Ver, versionRel);
+ Resource document2Ver = graph.getPossibleObject(document2, versionRelInv);
+ if (document2Ver != null)
+ unsetVersion(graph, document2, document2Ver, versionRelInv);
+
+ graph.claim(document1, versionRel, document2);
+
+ Resource lib = getLib(graph, document1);
+ if (lib != null) {
+ Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation);
+ String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType);
+ if ("TREE".equals(type) && relation != null) {
+ if (versionRel.equals(doc.HasOlderVersion)) {
+ graph.deny(document2, graph.getInverse(relation));
+ graph.claim(document1,relation,document2);
+ } else {
+ graph.deny(document1, graph.getInverse(relation));
+ graph.claim(document2,relation,document1);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Unlinks document version relationship between two documents.
+ * @param graph
+ * @param document1
+ * @param document2
+ * @param versionRel
+ * @throws DatabaseException
+ */
+ public static void unsetVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException {
+ DocumentResource doc = DocumentResource.getInstance(graph);
+ if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion)))
+ throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel));
+
+ graph.deny(document1, versionRel,document2);
+ Resource lib = getLib(graph, document1);
+ if (lib != null) {
+ Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation);
+ String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType);
+ if ("TREE".equals(type) && relation != null) {
+ if (versionRel.equals(doc.HasOlderVersion)) {
+ graph.deny(document1, relation);
+ graph.claim(lib,relation,document2);
+ FileDocumentUtil.createUniqueName(graph, document2);
+ } else {
+ graph.deny(document1, graph.getInverse(relation));
+ graph.claim(lib,relation,document1);
+ FileDocumentUtil.createUniqueName(graph, document1);
+ }
+ }
+
+ }
+ }
+
+ private static Resource getLib(ReadGraph graph, Resource document) throws DatabaseException {
+ Layer0 l0 = Layer0.getInstance(graph);
+ DocumentResource doc = DocumentResource.getInstance(graph);
+ Resource r = document;
+ while (true) {
+ Resource lib = graph.getPossibleObject(r, l0.PartOf);
+ if (lib == null)
+ lib = graph.getPossibleObject(r, l0.IsOwnedBy);
+ if (lib == null)
+ lib = graph.getPossibleObject(r, l0.IsDependencyOf);
+ if (lib == null)
+ return null;
+ if (!graph.isInstanceOf(lib, doc.Document))
+ return lib;
+ r = lib;
+ }
+ }
+}
}
@Override
- public void export(Document document, PdfWriter writer) throws DocumentException {
+ public int export(Document document, PdfWriter writer) throws DocumentException {
File temp = Simantics.getTempfile("wikiPdfExport", "pdf");
try {
temp.getParentFile().mkdirs();
PhantomJSDriver.print(html, settings, temp);
+ int result = 0;
PdfContentByte cb = writer.getDirectContent();
PdfReader reader = new PdfReader(new BufferedInputStream(new FileInputStream(temp)));
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
//add the page to the destination pdf
float pts = Utilities.millimetersToPoints(10);
cb.addTemplate(page, pts, pts);
+ ++result;
}
+ return result;
} catch (IOException e) {
throw new DocumentException(e);
--- /dev/null
+package org.simantics.document;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.graphfile.ontology.GraphFileResource;
+import org.simantics.graphfile.util.GraphFileUtil;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.ui.ExceptionUtils;
+
+/**
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class FileDocumentUtil {
+
+ /**
+ * Imports file, sets its L0.hasName, and and adds it to a library
+ *
+ * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
+ *
+ * @param fileName
+ * @param lib
+ * @param rel
+ * @throws DatabaseException
+ */
+ public static Resource importFile(final String fileName, final Resource lib, final Resource rel) throws DatabaseException {
+ return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
+ @Override
+ public Resource perform(WriteGraph graph) throws DatabaseException {
+ return importFile(graph, fileName,lib,rel);
+ }
+ });
+
+
+ }
+
+ public static void importFileAsync(final String fileName, final Resource lib, final Resource rel) {
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ importFile(graph, fileName,lib,rel);
+
+ }
+ },new org.simantics.utils.datastructures.Callback<DatabaseException>() {
+
+ @Override
+ public void run(DatabaseException parameter) {
+ if (parameter != null)
+ ExceptionUtils.logAndShowError("Cannot import file " + fileName, parameter);
+
+ }
+ });
+
+
+ }
+
+ /**
+ * Imports file, sets its L0.HasName, and and adds it to a library
+ *
+ * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
+ *
+ * @param graph
+ * @param fileName
+ * @param lib
+ * @param rel
+ * @throws DatabaseException
+ */
+ public static Resource importFile(WriteGraph graph, String fileName, Resource lib, Resource rel) throws DatabaseException{
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource fileResource = importFile(graph, fileName);
+ graph.claim(lib, rel, fileResource);
+ File file = new File(fileName);
+ String name = file.getName();
+ graph.claimLiteral(fileResource, l0.HasName, name);
+ setUniqueName(graph, fileResource, lib, rel);
+ return fileResource;
+ }
+
+ public static Resource importFileWithName(WriteGraph graph, String fileName) throws DatabaseException{
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource fileResource = importFile(graph, fileName);
+ File file = new File(fileName);
+ String name = file.getName();
+ graph.claimLiteral(fileResource, l0.HasName, name);
+ return fileResource;
+ }
+
+ /**
+ * Imports folder of documents recursively (including all sub folders).
+ * @param graph
+ * @param folderName Name of imported folder
+ * @param lib Library, where imported folder is attached.
+ * @param folderType Type of folders
+ * @param relation Relation used to create file/folder hierarchy
+ * @return the imported folder
+ * @throws DatabaseException
+ */
+ public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource lib, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
+ Resource folderRes = importFolderWithName(graph, folderName, folderType, relation,monitor);
+ graph.claim(lib, relation, folderRes);
+ FileDocumentUtil.createUniqueName(graph, folderRes);
+ return folderRes;
+ }
+
+ /**
+ * Imports folder of documents recursively (including all sub folders).
+ * @param graph
+ * @param folderName Name of imported folder
+ * @param folderType Type of folders
+ * @param relation Relation used to create file/folder hierarchy
+ * @param monitor ProgessMonitor or null
+ * @return the imported folder
+ * @throws DatabaseException
+ */
+ public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
+ Layer0 l0 = Layer0.getInstance(graph);
+ File folder = new File(folderName);
+ Resource rootFolderRes = graph.newResource();
+ graph.claim(rootFolderRes, l0.InstanceOf, folderType);
+ graph.claimLiteral(rootFolderRes, l0.HasName, folder.getName());
+ importFolder(graph, folder, rootFolderRes, relation, monitor);
+ return rootFolderRes;
+ }
+
+ /**
+ * Imports folder of documents recursively (including all sub folders).
+ * @param graph
+ * @param folder Imported folder
+ * @param folderResource Resource folder matching file system folder
+ * @param relation Relation used to create file/folder hierarchy
+ * @throws DatabaseException
+ */
+ public static void importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
+ if (monitor != null) {
+ int count = _countFiles(folder);
+ monitor.beginTask("Import files", count);
+ }
+ _importFolder(graph, folder, folderResource, relation, monitor);
+ if (monitor != null)
+ monitor.done();
+ }
+
+ private static void _importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
+ Layer0 l0 = Layer0.getInstance(graph);
+ File files[] = folder.listFiles();
+ for (File f : files) {
+ if (f.isDirectory()) {
+ Resource newFolderRes = graph.newResource();
+ graph.claim(newFolderRes, l0.InstanceOf, graph.getSingleType(folderResource));
+ graph.claim(folderResource, relation, newFolderRes);
+ graph.claimLiteral(newFolderRes, l0.HasName, f.getName());
+ _importFolder(graph, f, newFolderRes, relation,monitor);
+ } else {
+ Resource fileRes = null;
+ if (isUrl(f)) {
+ } else {
+ fileRes = importURL(graph, f);
+ fileRes = importFileWithName(graph, f.getAbsolutePath());
+ }
+ graph.claim(folderResource, relation, fileRes);
+ if (monitor != null)
+ monitor.worked(1);
+ }
+ }
+ }
+
+ private static int _countFiles(File folder) {
+
+ int count = 0;
+ File files[] = folder.listFiles();
+ for (File f : files) {
+ if (f.isDirectory()) {
+ count += _countFiles(f);
+ } else {
+ count++;
+ }
+ }
+ return count;
+ }
+
+
+ public static void createUniqueName(WriteGraph graph, Resource document) throws DatabaseException {
+ Layer0 l0 = Layer0.getInstance(graph);
+ Resource lib = graph.getPossibleObject(document, l0.PartOf);
+ if (lib == null)
+ return;
+ setUniqueName(graph, document, lib, l0.ConsistsOf);
+ }
+
+ public static void setUniqueName(WriteGraph graph, Resource res, Resource lib, Resource rel) throws DatabaseException{
+ Layer0 l0 = Layer0.getInstance(graph);
+ Set<String> names = new HashSet<String>();
+ for (Resource r : graph.getObjects(lib, rel)) {
+ if (r.equals(res))
+ continue;
+ names.add((String)graph.getRelatedValue(r, l0.HasName));
+ }
+ String name = graph.getRelatedValue(res, l0.HasName);
+ if (!names.contains(name))
+ return;
+ int i = 1;
+ while (true) {
+ String proposal = name +" (" + i +")";
+ if (!names.contains(proposal)) {
+ graph.claimLiteral(res, l0.HasName, proposal);
+ return;
+ }
+ i++;
+ }
+
+ }
+
+ /**
+ * Imports a file
+ *
+ * @param graph
+ * @param fileName
+ * @return
+ * @throws DatabaseException
+ */
+ public static Resource importFile(WriteGraph graph, String fileName) throws DatabaseException{
+ Layer0 l0 = Layer0.getInstance(graph);
+ DocumentResource doc = DocumentResource.getInstance(graph);
+
+ Resource fileResource = graph.newResource();
+ graph.claim(fileResource, l0.InstanceOf, doc.FileDocument);
+ try {
+ GraphFileUtil.toGraph(graph,fileName, fileResource);
+
+ } catch (IOException e) {
+ throw new DatabaseException(e);
+ }
+ return fileResource;
+
+ }
+
+ /**
+ * Exports graph folder recursively to file system.
+ * @param graph
+ * @param folderResource
+ * @param folder
+ * @param relation
+ * @throws DatabaseException
+ */
+ public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, boolean useResourceNames, final IProgressMonitor monitor) throws Exception{
+ Simantics.getSession().syncRequest(new ReadRequest() {
+
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ try {
+ exportDocumentFolder(graph, folderResource, folder, relation, useResourceNames, monitor);
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+
+ }
+ });
+ }
+
+
+ /**
+ * Exports graph folder recursively to file system.
+ * @param graph
+ * @param folderResource
+ * @param folder
+ * @param relation
+ * @throws DatabaseException
+ */
+ public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, boolean useResourceNames, IProgressMonitor monitor) throws Exception{
+ Layer0 l0 = Layer0.getInstance(graph);
+ DocumentResource doc = DocumentResource.getInstance(graph);
+ GraphFileResource gf = GraphFileResource.getInstance(graph);
+ Set<String> names = new HashSet<String>();
+ Collection<Resource> folderType = graph.getPrincipalTypes(folderResource);
+ for (Resource r : graph.getObjects(folderResource, relation)) {
+ if (graph.isInstanceOf(r, doc.Document)) {
+ String name = null;
+ boolean canExport = false;
+ if (graph.isInstanceOf(r, doc.FileDocument)) {
+ name = graph.getRelatedValue(r, useResourceNames ? gf.HasResourceName : l0.HasName);
+ canExport = true;
+ } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
+ name = graph.getRelatedValue(r, l0.HasName) +".url";
+ canExport = true;
+ }
+ if (canExport) {
+ name = resolveName(folder, name, names, true);
+ File file = new File(folder.getAbsolutePath()+"/"+name);
+ if (graph.isInstanceOf(r, doc.FileDocument)) {
+ GraphFileUtil.writeDataToFile(graph,r, file);
+ } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
+ String url = graph.getRelatedValue(r, doc.HasUrl);
+ String n = graph.getRelatedValue(r, l0.HasName);
+ exportUrl(file, n, url);
+ }
+ if (monitor != null)
+ monitor.worked(1);
+ }
+
+ } else {
+ Collection<Resource> type = graph.getPrincipalTypes(r);
+ if (type.size() == folderType.size() && folderType.containsAll(type)) {
+ String name = graph.getRelatedValue(r, l0.HasName);
+ name = resolveName(folder, name, names, false);
+ File subFolder = new File(folder.getAbsolutePath()+"/"+name);
+ if (!subFolder.exists()) {
+ if (!subFolder.mkdir()) {
+ // TODO : error.
+ continue;
+ }
+ }
+ exportDocumentFolder(graph, r, subFolder, relation, useResourceNames, monitor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Print URL to a file (Windows specific format?)
+ * @param toFile
+ * @param url
+ * @throws DatabaseException
+ */
+ private static void exportUrl(File toFile, String name, String url) throws Exception{
+ PrintStream os = new PrintStream(toFile,"UTF-8");
+ os.println("[InternetShortcut]");
+ os.println("URL="+url);
+ os.println("name="+name);
+ os.flush();
+ os.close();
+ }
+
+ public static Resource importURL(WriteGraph graph, File file) throws Exception{
+ String s = null;
+ String url = null;
+ String name = null;
+ BufferedReader is = null;
+ try {
+ is = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+ while ((s = is.readLine()) != null) {
+ if (s.startsWith("URL=")) {
+ url = s.substring(4);
+ } else if (s.startsWith("name=")) {
+ name = s.substring(5);
+ }
+ }
+ } finally {
+ if (is != null)
+ is.close();
+ }
+
+ if (url == null)
+ return null;
+
+ Layer0 l0 = Layer0.getInstance(graph);
+ DocumentResource doc = DocumentResource.getInstance(graph);
+
+ Resource fileResource = graph.newResource();
+ graph.claim(fileResource, l0.InstanceOf, doc.UrlDocument);
+ if (name == null) {
+ name = file.getName();
+ name = unescape(name);
+ name = name.substring(0,name.length()-4);
+ }
+ graph.claimLiteral(fileResource, l0.HasName, name);
+ graph.claimLiteral(fileResource, doc.HasUrl, url);
+ return fileResource;
+ }
+
+ private static boolean isUrl(File file) throws Exception{
+ return (file.getAbsolutePath().endsWith(".url"));
+ }
+
+ private static final char ESCAPE = '%';
+
+ private static String escape(String s) {
+
+ int len = s.length();
+ StringBuilder sb = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ char ch = s.charAt(i);
+ if (ch < ' ' || ch >= 0x7F || ch == '/' || ch == '\\' || ch == ':' || ch == ESCAPE) {
+ sb.append(ESCAPE);
+ if (ch < 0x10) {
+ sb.append('0');
+ }
+ sb.append(Integer.toHexString(ch));
+ } else {
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String unescape(String s) {
+ int len = s.length();
+ StringBuilder sb = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ char ch = s.charAt(i);
+ if (ch == ESCAPE) {
+ String num = "0x";
+ num += s.charAt(++i);
+ num += s.charAt(++i);
+ ch = (char)Integer.decode(num).intValue();
+ }
+ sb.append(ch);
+ }
+ return sb.toString();
+
+ }
+
+ private static String resolveName(File parentFolder, String proposal, Set<String> used, boolean file) {
+ String current = escape(proposal);
+ int i = 0;
+ if (file) {
+ while (true) {
+ i++;
+ if (used.contains(current)) {
+ current = createFileName(proposal, i);
+ } else {
+ File subFile = new File(parentFolder.getAbsolutePath()+"/"+current);
+ if (!subFile.exists())
+ break;
+ if (subFile.exists() && subFile.isFile() && subFile.canWrite()) {
+ break;
+ }
+ }
+ }
+ } else {
+ while (true) {
+ i++;
+ if (used.contains(current)) {
+ current = proposal+i;
+ } else {
+ File subFolder = new File(parentFolder.getAbsolutePath()+"/"+current);
+ if (!subFolder.exists())
+ break;
+ if (subFolder.exists() && subFolder.isDirectory()) {
+ break;
+ }
+ }
+ }
+ }
+ used.add(current);
+ return current;
+ }
+
+ private static String createFileName(String original, int i) {
+ int extIndex = original.lastIndexOf(".");
+ if (extIndex == -1)
+ return original+i;
+ return original.substring(0,extIndex) + i + original.substring(extIndex);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.document;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.simantics.DatabaseJob;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+
+/**
+ * Action for importing files as documents.
+ *
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class ImportDocument extends AddDocumentAction {
+
+
+ public ImportDocument(ReadGraph graph, String relationUri) throws DatabaseException {
+ super(graph, relationUri);
+ }
+
+ @Override
+ public Runnable create(Object target) {
+ if(!(target instanceof Resource))
+ return null;
+ final Resource resource = (Resource)target;
+ return new Runnable() {
+
+ @Override
+ public void run() {
+ FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN | SWT.MULTI);
+ // TODO : is there any way to read file/executable bindings from OS?
+ // if is, use those extensions to filter this list.
+ // note: in windows using "reg query ..." to read bindings form registry would work.
+ // Note : If the above mentioned filtering is implemented it should be made optional / configurable.
+ dialog.setFilterExtensions(new String[]{"*.*"});
+ if (dialog.open() == null) return;
+
+ String filterPath = dialog.getFilterPath();
+ String[] filenames = dialog.getFileNames();
+
+ ImportJob job = new ImportJob(filenames.length > 1 ? "Import files" : "Import file", resource, filterPath, filenames);
+ job.setUser(true);
+ job.schedule();
+ }
+ };
+ }
+
+ private class ImportJob extends DatabaseJob {
+
+ public ImportJob(String name, Resource resource, String path, String[] filenames) {
+ super(name);
+ this.resource = resource;
+ this.path = path;
+ this.filenames = filenames;
+ }
+
+ Resource resource;
+ String path;
+ String[] filenames;
+
+ @Override
+ protected IStatus run(final IProgressMonitor monitor) {
+ monitor.beginTask("Importing...", filenames.length);
+ try {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ try {
+ graph.markUndoPoint();
+ for (String filename : filenames) {
+ File f = new File(path, filename);
+ Resource newDoc = FileDocumentUtil.importFileWithName(graph, f.getAbsolutePath());
+ linkDocument(graph, resource, newDoc);
+ monitor.worked(1);
+ }
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+ }
+ });
+ return new Status(IStatus.OK, Activator.PLUGIN_ID, "Import succesful.");
+ } catch (DatabaseException e) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed.", e);
+ } finally {
+ monitor.done();
+ }
+ }
+ }
+
+}
import com.lowagie.text.DocumentException;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.DefaultFontMapper;
import com.lowagie.text.pdf.PdfBoolean;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfName;
writer.fos = new FileOutputStream(writer.outputFile);
writer.pdfCopy = new PdfCopy(writer.document, writer.fos);
writer.pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
- writer.fontMapper = new DefaultFontMapper();
+ writer.fontMapper = FontMapping.defaultFontMapper();
writer.options = options;
writer.ctx = ctx;
try {
int n = reader.getNumberOfPages();
- for (int i = 0; i < n; ) {
- Rectangle pageSize = reader.getPageSizeWithRotation(n);
+ for (int i = 1; i <= n; ++i) {
+ Rectangle pageSize = reader.getPageSizeWithRotation(i);
- PdfImportedPage imp = pdfCopy.getImportedPage(reader, ++i);
+ PdfImportedPage imp = pdfCopy.getImportedPage(reader, i);
PdfCopy.PageStamp ps = pdfCopy.createPageStamp(imp);
PdfContentByte over = ps.getOverContent();
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.export.core.pdf;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.lowagie.text.FontFactory;
+import com.lowagie.text.pdf.DefaultFontMapper;
+import com.lowagie.text.pdf.FontMapper;
+
+/**
+ * A utility class for constructing properly initialize iText {@link FontMapper}
+ * instances.
+ *
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class FontMapping {
+
+ private static final AtomicBoolean fontFactoryInitialized = new AtomicBoolean();
+
+ public static FontMapper defaultFontMapper() {
+ // NOTE: recreation is intentional because users might add fonts between exports.
+ // At some point, perhaps we could listen to file system changes in these locations
+ // and only then recreate the mapper.
+ return createDefaultFontMapper();
+ }
+
+ public static FontMapper createDefaultFontMapper() {
+ initializeFontFactory();
+ DefaultFontMapper mapper = new DefaultFontMapper();
+ insertDirectories(mapper);
+ return mapper;
+ }
+
+ private static void insertDirectories(DefaultFontMapper mapper) {
+ switch (OSType.calculate()) {
+ case APPLE:
+ mapper.insertDirectory("/Library/Fonts");
+ mapper.insertDirectory("/System/Library/Fonts");
+
+ case LINUX:
+ case SUN:
+ mapper.insertDirectory("/usr/share/X11/fonts");
+ mapper.insertDirectory("/usr/X/lib/X11/fonts");
+ mapper.insertDirectory("/usr/openwin/lib/X11/fonts");
+ mapper.insertDirectory("/usr/share/fonts");
+ mapper.insertDirectory("/usr/X11R6/lib/X11/fonts");
+ break;
+
+ case WINDOWS:
+ String windir = System.getenv("WINDIR");
+ if (windir != null && !windir.isEmpty()) {
+ mapper.insertDirectory(windir + "\\Fonts");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ private static void initializeFontFactory() {
+ if (!fontFactoryInitialized.compareAndSet(false, true))
+ return;
+
+ switch (OSType.calculate()) {
+ case APPLE:
+ FontFactory.registerDirectory("/Library/Fonts");
+ FontFactory.registerDirectory("/System/Library/Fonts");
+
+ case LINUX:
+ case SUN:
+ FontFactory.registerDirectory("/usr/share/X11/fonts", true);
+ FontFactory.registerDirectory("/usr/X/lib/X11/fonts", true);
+ FontFactory.registerDirectory("/usr/openwin/lib/X11/fonts", true);
+ FontFactory.registerDirectory("/usr/share/fonts", true);
+ FontFactory.registerDirectory("/usr/X11R6/lib/X11/fonts", true);
+ break;
+
+ case WINDOWS:
+ String windir = System.getenv("WINDIR");
+ if (windir != null && !windir.isEmpty()) {
+ FontFactory.registerDirectory(windir + "\\Fonts");
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ static enum OSType {
+ APPLE, LINUX, SUN, WINDOWS, UNKNOWN;
+
+ public static OSType calculate() {
+ String osName = System.getProperty("os.name");
+ assert osName != null;
+ osName = osName.toLowerCase();
+ if (osName.startsWith("mac os x"))
+ return APPLE;
+ if (osName.startsWith("windows"))
+ return WINDOWS;
+ if (osName.startsWith("linux"))
+ return LINUX;
+ if (osName.startsWith("sun"))
+ return SUN;
+ return UNKNOWN;
+ }
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.export.core.pdf;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.pdf.BadPdfFormatException;
+import com.lowagie.text.pdf.ColumnText;
+import com.lowagie.text.pdf.PdfContentByte;
+import com.lowagie.text.pdf.PdfCopy;
+import com.lowagie.text.pdf.PdfImportedPage;
+import com.lowagie.text.pdf.PdfReader;
+import com.lowagie.text.pdf.PdfWriter;
+
+/**
+ * PDF page numbering related post-processing utilities using iText.
+ *
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class PageNumbering {
+
+ public static enum NumberingFormat {
+ PAGE_SLASH_TOTAL_PAGES
+ }
+
+ public static enum Position {
+ BOTTOM_LEFT,
+ BOTTOM_RIGHT,
+ TOP_LEFT,
+ TOP_RIGHT,
+ }
+
+ private static int pageNumberAlignment(Position positioning) {
+ switch (positioning) {
+ case BOTTOM_LEFT:
+ case TOP_LEFT: return Element.ALIGN_LEFT;
+
+ case BOTTOM_RIGHT:
+ case TOP_RIGHT:
+ default: return Element.ALIGN_RIGHT;
+ }
+ }
+
+ private static Point2D.Float pageNumberPosition(Position positioning, Rectangle pageSize, Font font) {
+ switch (positioning) {
+ case TOP_LEFT:
+ return new Point2D.Float(12, pageSize.getHeight() - 12 - font.getCalculatedSize()*0.8f);
+ case TOP_RIGHT:
+ return new Point2D.Float(pageSize.getWidth() - 12, pageSize.getHeight() - 12 - font.getCalculatedSize()*0.8f);
+ case BOTTOM_LEFT:
+ return new Point2D.Float(12, 12);
+ case BOTTOM_RIGHT:
+ default:
+ return new Point2D.Float(pageSize.getWidth() - 12, 12);
+ }
+ }
+
+ public static String formatPageNumber(NumberingFormat format, int pageNumber, int totalPages) {
+ switch (format) {
+ case PAGE_SLASH_TOTAL_PAGES: return String.format("%d / %d", pageNumber, totalPages);
+ default:
+ throw new UnsupportedOperationException("Unsupported numbering format: " + format);
+ }
+ }
+
+ public static void addPageNumber(
+ PdfCopy pdfCopy,
+ PdfReader sourceReader,
+ int sourcePageNumber,
+ int currentPageNumber,
+ int totalPages,
+ Font font,
+ Position positioning,
+ NumberingFormat format)
+ throws IOException, BadPdfFormatException
+ {
+ Rectangle pageSize = sourceReader.getPageSizeWithRotation(sourcePageNumber);
+ PdfImportedPage imp = pdfCopy.getImportedPage(sourceReader, sourcePageNumber);
+ PdfCopy.PageStamp ps = pdfCopy.createPageStamp(imp);
+ PdfContentByte over = ps.getOverContent();
+ String text = formatPageNumber(format, currentPageNumber, totalPages);
+ Point2D.Float pos = pageNumberPosition(positioning, pageSize, font);
+ int alignment = pageNumberAlignment(positioning);
+ ColumnText.showTextAligned(over, alignment, new Phrase(text, font), pos.x, pos.y, 0);
+ ps.alterContents();
+ pdfCopy.addPage(imp);
+ }
+
+ public static void addPageNumbers(
+ IProgressMonitor monitor,
+ Path inputFile,
+ Path outputFile,
+ Position positioning,
+ NumberingFormat format,
+ Font pageNumberFont)
+ throws IOException, DocumentException
+ {
+ PdfReader reader = null;
+ try {
+ reader = new PdfReader(inputFile.toString());
+ int totalPages = reader.getNumberOfPages();
+ int currentPage = 1;
+
+ SubMonitor mon = SubMonitor.convert(monitor, totalPages);
+
+ try (OutputStream fos = Files.newOutputStream(outputFile)) {
+ Document document = new Document();
+ PdfCopy pdfCopy = new PdfCopy(document, fos);
+ pdfCopy.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
+ document.open();
+ try {
+ for (int i = 1; i <= totalPages; ++i) {
+ mon.subTask(i + "/" + totalPages);
+ PageNumbering.addPageNumber(pdfCopy, reader, i,
+ currentPage++, totalPages,
+ pageNumberFont,
+ positioning,
+ format);
+ }
+ } finally {
+ if (document != null && document.isOpen())
+ document.close();
+ if (pdfCopy != null)
+ pdfCopy.close();
+ }
+ }
+ } finally {
+ if (reader != null)
+ reader.close();
+ }
+
+ }
+
+ public static void addPageNumbers(
+ IProgressMonitor monitor,
+ Path inputFile,
+ Path outputFile,
+ Position positioning,
+ NumberingFormat format)
+ throws IOException, DocumentException
+ {
+ addPageNumbers(monitor, inputFile, outputFile, positioning, format, new Font(Font.HELVETICA, 8));
+ }
+
+}
\ No newline at end of file
org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100.v20150407-1430",
org.eclipse.e4.core.di,
org.eclipse.e4.ui.services,
- org.simantics.fileimport;bundle-version="1.0.0"
+ org.simantics.fileimport;bundle-version="1.0.0",
+ org.slf4j.api
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: javax.inject;version="1.0.0"
Bundle-ActivationPolicy: lazy
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
+import java.util.function.Consumer;
import javax.inject.Named;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.simantics.fileimport.FileImportService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ImportFileHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ImportFileHandler.class);
+
@CanExecute
public boolean canExecute() {
return !FileImportService.supportedExtensionsWithFilters().isEmpty();
final String fileName = dialog.open();
if (fileName == null)
return;
- FileImportService.performFileImport(Paths.get(fileName), Optional.empty());
+
+ FileImportService.performFileImport(Paths.get(fileName), Optional.of((Consumer<Throwable>) t -> {
+ LOGGER.error("Could not import file " + fileName, t);
+ }));
}
}
\ No newline at end of file
org.simantics,
org.simantics.graphfile;bundle-version="0.1.0",
org.simantics.graphfile.ontology;bundle-version="0.1.0",
- org.simantics.modeling;bundle-version="1.1.1"
+ org.simantics.modeling;bundle-version="1.1.1",
+ org.slf4j.api
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.simantics.fileimport
getUploadedFiles :: () -> <Proc> MMap.T String Long
removeFileForId :: Long -> <Proc> ()
+
+importJava "org.simantics.fileimport.FileImportService" where
+ performFileImport :: String -> String -> <Proc> String
+
getUploadedDropinFiles :: () -> <Proc> [Long]
getUploadedDropinFiles dummy = do
files = getUploadedFiles ()
public class Activator implements BundleActivator {
- private static BundleContext context;
+ private static BundleContext context;
+ private static Path modelsFolder = null;
private static Path dropinsFolder = null;
static BundleContext getContext() {
return dropinsFolder;
}
+ public static Path getModelsFolder() throws IOException {
+ if (modelsFolder == null) {
+ IPath state = Platform.getStateLocation(context.getBundle());
+ modelsFolder = Paths.get(state.append("models").toOSString());
+ if (!Files.exists(modelsFolder))
+ Files.createDirectories(modelsFolder);
+ }
+ return modelsFolder;
+ }
+
}
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
+import org.simantics.databoard.util.Base64;
import org.simantics.fileimport.dropins.FileImportDropins;
+import org.simantics.utils.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Utility class for Simantics File import functions
*/
public class FileImportService {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FileImportService.class);
+
private FileImportService() {}
public static final String DB_FILE = ".simanticsdb";
serviceReferences = Activator.getContext().getAllServiceReferences(IGenericFileImport.class.getName(),
null);
} catch (InvalidSyntaxException e) {
- e.printStackTrace();
+ LOGGER.error("Could not get service references for IGenericFileImport!", e);
}
if (serviceReferences.length == 0)
return Collections.emptyList();
return extensionsWithFilters;
}
+
+ private static class ConsumerHolder implements Consumer<Throwable> {
+
+ private Throwable throwable;
+
+ @Override
+ public void accept(Throwable t) {
+ throwable = t;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+
+ }
+
+ public static String performFileImport(String base64, String name) throws Throwable {
+ byte[] bytes = Base64.decode(base64);
+ Path file = Activator.getModelsFolder().resolve(name);
+ Files.write(file, bytes);
+
+ ConsumerHolder holder = new ConsumerHolder();
+ String result = performFileImport(file, Optional.of(holder));
+ if (holder.getThrowable() != null)
+ throw holder.getThrowable();
+ return result;
+ }
/**
* Method that performs the import of the given file. This method is called when e.g. {@link FileImportDropins} watcher detects {@link java.nio.file.StandardWatchEventKinds.ENTRY_CREATE} operation
* @param file Path file to be imported
* @param callback Optional callback which can be used to catch Throwables thrown in the import process
*/
- public static void performFileImport(Path file, Optional<Consumer<Throwable>> callback) {
- if (file.getFileName().toString().equals(DB_FILE))
- return;
+ public static String performFileImport(Path file, Optional<Consumer<Throwable>> callback) {
+ if (file.getFileName().toString().equals(DB_FILE)) {
+ return null;
+ }
+ String result = "Import failed";
Optional<IGenericFileImport> serviceOp = findServiceForFileExtension(file);
- serviceOp.ifPresent(service -> {
+ if (serviceOp.isPresent()) {
+ IGenericFileImport service = serviceOp.get();
try {
Optional<String> resource = service.perform(file);
saveResourceForPath(file, resource);
+ result = resource.get();
} catch (Throwable t) {
if (callback.isPresent()) {
callback.get().accept(t);
} else {
- t.printStackTrace();
+ LOGGER.error("Could not import file " + file, t);
}
}
- });
+ } else {
+ LOGGER.warn("Could not find service for importing file " + file);
+ if (callback.isPresent())
+ callback.get().accept(new Exception("Could not find IGenericFileImport service for file " + file));
+ }
+ return result;
}
import java.util.Optional;
import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
import org.simantics.graphfile.util.GraphFileUtil;
public class FileReferenceFileImport extends SimanticsResourceFileImport {
- private static final Map<String, String> ALLOWED_EXTENSIONS = Collections.singletonMap("*.asd", "All files");
+ private static final Map<String, String> ALLOWED_EXTENSIONS = Collections.singletonMap("*", "All files");
@Override
- public Optional<Resource> perform(Resource parent, Path file) {
- try {
- return Optional.of(GraphFileUtil.createFileReference(parent, file));
- } catch (DatabaseException e) {
- e.printStackTrace();
- return Optional.empty();
- }
+ public Optional<Resource> perform(Resource parent, Path file) throws Exception {
+ return Optional.of(GraphFileUtil.createFileReference(parent, file));
}
@Override
}
@Override
- public Optional<Resource> perform(Resource parent, Path file) {
+ public Optional<Resource> perform(Resource parent, Path file) throws Exception {
final String name = file.getFileName().toString();
- try {
- return Optional.of(Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
+ return Optional.of(Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
- @Override
- public Resource perform(WriteGraph graph) throws DatabaseException {
- return ModelingUtils.createLibrary(graph, parent, name);
- }
- }));
- } catch (DatabaseException e) {
- e.printStackTrace();
- return Optional.empty();
- }
+ @Override
+ public Resource perform(WriteGraph graph) throws DatabaseException {
+ return ModelingUtils.createLibrary(graph, parent, name);
+ }
+ }));
}
}
import org.simantics.fileimport.dropins.FileImportDropins;
import org.simantics.layer0.Layer0;
import org.simantics.utils.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* SCL interface for Simantics File Import Functionality
*
*/
public class DropinsSCL {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DropinsSCL.class);
public static void watchDropinsFolder() {
FileImportDropins.watchDropinsFolder();
public static void uploadToDropinsBase64(String base64, String fileName) {
// ensure that watcher is awake
FileImportDropins.watchDropinsFolder();
+ Path rootFolder = null;
try {
- Path rootFolder = Activator.getDropinsFolder();
+ rootFolder = Activator.getDropinsFolder();
Path newFile = rootFolder.resolve(fileName);
if (Files.exists(newFile)) {
newFile = findFreshFileName(rootFolder, fileName);
byte[] bytes = Base64.decode(base64);
FileUtils.writeFile(newFile.toFile(), bytes);
} catch (IOException e) {
- e.printStackTrace();
+ LOGGER.error("Could not upload base64 to file " + (rootFolder != null ? rootFolder.resolve(fileName).toAbsolutePath() : ""), e);
}
}
org.simantics.utils.thread,
org.simantics.utils.thread.swt,
org.simantics.utils.ui;bundle-version="1.0.0",
- javax.vecmath;bundle-version="1.0.0",
org.apache.commons.collections;bundle-version="3.2.1",
+ org.apache.commons.math3,
gnu.trove3;bundle-version="3.0.0",
org.simantics.scenegraph;bundle-version="1.1.1";visibility:=reexport,
org.simantics.threadlog;bundle-version="1.0.0";resolution:=optional,
private transient boolean closed = false;
protected ICanvasContext canvasContext;
+ private boolean useVolatileImage = true;
+
// Marks the content dirty
protected IContentListener contentListener = new IContentListener() {
@Override
public IHintContext getHintContext() {
return hintCtx;
}
+
+ public void setUseVolatileImage(boolean useVolatileImage) {
+ this.useVolatileImage = useVolatileImage;
+ }
+
+ public boolean isUseVolatileImage() {
+ return useVolatileImage;
+ }
private void paintScenegraph(Graphics2D g2d, Rectangle controlBounds) {
Color bg = getBackground();
startmem = Runtime.getRuntime().freeMemory();
start = System.nanoTime();
}
- VolatileImage buffer = paintToVolatileImage(g2d, b);
+ VolatileImage buffer = null;
+ if (useVolatileImage)
+ buffer = paintToVolatileImage(g2d, b);
if (closed)
return;
if (DebugPolicy.PERF_CHASSIS_RENDER_FRAME) {
ConnectionNode holder = e.getHint(sgKey);
if (holder == null) {
holder = parentNode.addNode(ElementUtils.generateNodeId(e), ConnectionNode.class);
+ holder.setKey(e.getHint(ElementHints.KEY_OBJECT));
holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e));
e.setHint(sgKey, holder);
holder.setZIndex(parentNode.getNodeCount() + 1);
SingleElementNode holder = e.getHint(sgKey);
if (holder == null) {
holder = parentNode.addNode(ElementUtils.generateNodeId(e), SingleElementNode.class);
+ holder.setKey(e.getHint(ElementHints.KEY_OBJECT));
holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e));
e.setHint(sgKey, holder);
holder.setZIndex(parentNode.getNodeCount() + 1);
// If the previously available node is not a parent of the specified
// node create a new node under the specified parent and set that
// as the node of the specified element.
- if (!node.getParent().equals(withParentNode)) {
+ if (!withParentNode.equals(node.getParent())) {
node = nodeId != null ? withParentNode.getOrCreateNode(nodeId, nodeClass) : withParentNode.addNode(nodeClass);
forElement.setHint(withNodeKey, node);
if (nodeCreationCallback != null)
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - #7119 refactoring
*******************************************************************************/
package org.simantics.g2d.element.handler.impl;
*/
public class Terminals implements TerminalLayout, TerminalTopology {
- private static final long serialVersionUID = -6532093690907028016L;
+ private static final long serialVersionUID = -6532093690907028016L;
- private final Map<Terminal, ObjectTerminal> terminalMap = new THashMap<Terminal, ObjectTerminal>();
- private final ArrayList<Terminal> terminals = new ArrayList<Terminal>();
+ protected final Map<Terminal, ObjectTerminal> terminalMap = new THashMap<>();
+ protected final ArrayList<Terminal> terminals = new ArrayList<>();
public Terminals(Collection<ObjectTerminal> ts) {
for (ObjectTerminal ti : ts) {
+++ /dev/null
-///*******************************************************************************
-// * Copyright (c) 2007, 2010 Association for Decentralized Information Management
-// * in Industry THTH ry.
-// * All rights reserved. This program and the accompanying materials
-// * are made available under the terms of the Eclipse Public License v1.0
-// * which accompanies this distribution, and is available at
-// * http://www.eclipse.org/legal/epl-v10.html
-// *
-// * Contributors:
-// * VTT Technical Research Centre of Finland - initial API and implementation
-// *******************************************************************************/
-//package org.simantics.g2d.elementclass;
-//
-//import java.awt.BasicStroke;
-//import java.awt.Color;
-//import java.awt.Font;
-//import java.awt.FontMetrics;
-//import java.awt.Graphics2D;
-//import java.awt.Rectangle;
-//import java.awt.Shape;
-//import java.awt.event.ActionEvent;
-//import java.awt.event.ActionListener;
-//import java.awt.geom.AffineTransform;
-//import java.awt.geom.Path2D;
-//import java.awt.geom.Point2D;
-//import java.awt.geom.Rectangle2D;
-//import java.util.EnumSet;
-//import java.util.Map;
-//
-//import javax.vecmath.Vector2d;
-//
-//import org.simantics.g2d.diagram.IDiagram;
-//import org.simantics.g2d.element.ElementClass;
-//import org.simantics.g2d.element.ElementHints;
-//import org.simantics.g2d.element.ElementUtils;
-//import org.simantics.g2d.element.IElement;
-//import org.simantics.g2d.element.SceneGraphNodeKey;
-//import org.simantics.g2d.element.handler.ElementHandler;
-//import org.simantics.g2d.element.handler.FillColor;
-//import org.simantics.g2d.element.handler.InternalSize;
-//import org.simantics.g2d.element.handler.LifeCycle;
-//import org.simantics.g2d.element.handler.Move;
-//import org.simantics.g2d.element.handler.Outline;
-//import org.simantics.g2d.element.handler.Rotate;
-//import org.simantics.g2d.element.handler.Scale;
-//import org.simantics.g2d.element.handler.SceneGraph;
-//import org.simantics.g2d.element.handler.StaticSymbol;
-//import org.simantics.g2d.element.handler.Text;
-//import org.simantics.g2d.element.handler.TextEditor;
-//import org.simantics.g2d.element.handler.Transform;
-//import org.simantics.g2d.element.handler.TextEditor.Modifier;
-//import org.simantics.g2d.element.handler.impl.BorderColorImpl;
-//import org.simantics.g2d.element.handler.impl.FillColorImpl;
-//import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
-//import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
-//import org.simantics.g2d.element.handler.impl.TextColorImpl;
-//import org.simantics.g2d.element.handler.impl.TextEditorImpl;
-//import org.simantics.g2d.element.handler.impl.TextFontImpl;
-//import org.simantics.g2d.element.handler.impl.TextImpl;
-//import org.simantics.g2d.image.Image;
-//import org.simantics.g2d.image.ProviderUtils;
-//import org.simantics.g2d.image.impl.AbstractImage;
-//import org.simantics.g2d.utils.Alignment;
-//import org.simantics.scenegraph.Node;
-//import org.simantics.scenegraph.g2d.G2DParentNode;
-//import org.simantics.scenegraph.g2d.nodes.MonitorNode;
-//import org.simantics.utils.datastructures.cache.IFactory;
-//import org.simantics.utils.datastructures.cache.IProvider;
-//import org.simantics.utils.datastructures.cache.ProvisionException;
-//import org.simantics.utils.datastructures.hints.IHintContext.Key;
-//import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
-//import org.simantics.utils.strings.format.MetricsFormat;
-//import org.simantics.utils.strings.format.MetricsFormatList;
-//
-///**
-// * @author Tuukka Lehtonen
-// */
-//public class MonitorClass {
-//
-// static final Font FONT = Font.decode("Helvetica 12");
-//
-// /**
-// * Back-end specific object describing the monitored component.
-// */
-// public static final Key KEY_MONITOR_COMPONENT = new KeyOf(Object.class, "MONITOR_COMPONENT");
-//
-// /**
-// * The valuation suffix string describing the monitored variable of the
-// * component described by {@link #KEY_MONITOR_COMPONENT}.
-// */
-// public static final Key KEY_MONITOR_SUFFIX = new KeyOf(String.class, "MONITOR_SUFFIX");
-//
-// public static final Key KEY_MONITOR_SUBSTITUTIONS = new KeyOf(Map.class, "MONITOR_SUBSTITUTIONS");
-// public static final Key KEY_MONITOR_GC = new KeyOf(Graphics2D.class, "MONITOR_GC");
-// public static final Key KEY_MONITOR_HEIGHT = new KeyOf(Double.class, "MONITOR_HEIGHT");
-// public static final Key KEY_NUMBER_FORMAT = new KeyOf(MetricsFormat.class, "NUMBER_FORMAT");
-// public static final Key KEY_TOOLTIP_TEXT = new KeyOf(String.class, "TOOLTIP_TEXT");
-//
-// /**
-// * If this hint is defined, the monitor will force its x-axis to match this
-// * angle. If this hint doesn't exist, the monitor will not force x-axis
-// * orientation.
-// */
-// public static final Key KEY_DIRECTION = new KeyOf(Double.class, "MONITOR_DIRECTION");
-//
-// public static final Key KEY_BORDER_WIDTH = new KeyOf(Double.class, "MONITOR_BORDER");
-//
-// public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "MONITOR_SG_NODE");
-//
-// final static BasicStroke STROKE = new BasicStroke(1.0f);
-//
-// public final static Alignment DEFAULT_HORIZONTAL_ALIGN = Alignment.CENTER;
-// public final static Alignment DEFAULT_VERTICAL_ALIGN = Alignment.CENTER;
-// public final static MetricsFormat DEFAULT_NUMBER_FORMAT = MetricsFormatList.METRICS_DECIMAL;
-//
-// public final static Color DEFAULT_FILL_COLOR = new Color(224, 224, 224);
-// public final static Color DEFAULT_BORDER_COLOR = Color.BLACK;
-//
-// public final static double DEFAULT_HORIZONTAL_MARGIN = 5.0;
-// public final static double DEFAULT_VERTICAL_MARGIN = 2.5;
-//
-// static Alignment getHorizontalAlignment(IElement e) {
-// return ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, DEFAULT_HORIZONTAL_ALIGN);
-// }
-//
-// static Alignment getVerticalAlignment(IElement e) {
-// return ElementUtils.getHintOrDefault(e, ElementHints.KEY_VERTICAL_ALIGN, DEFAULT_VERTICAL_ALIGN);
-// }
-//
-// static MetricsFormat getNumberFormat(IElement e) {
-// return ElementUtils.getHintOrDefault(e, KEY_NUMBER_FORMAT, DEFAULT_NUMBER_FORMAT);
-// }
-//
-// static void setNumberFormat(IElement e, MetricsFormat f) {
-// ElementUtils.setOrRemoveHint(e, KEY_NUMBER_FORMAT, f);
-// }
-//
-// static double getHorizontalMargin(IElement e) {
-// return DEFAULT_HORIZONTAL_MARGIN;
-// }
-//
-// static double getVerticalMargin(IElement e) {
-// return DEFAULT_VERTICAL_MARGIN;
-// }
-//
-// static Font getFont(IElement e) {
-// return ElementUtils.getHintOrDefault(e, ElementHints.KEY_FONT, FONT);
-// }
-//
-// public static class MonitorHandlerImpl implements MonitorHandler {
-// private static final long serialVersionUID = -4258875745321808416L;
-// public static final MonitorHandler INSTANCE = new MonitorHandlerImpl();
-// }
-//
-// static class Initializer implements LifeCycle {
-// private static final long serialVersionUID = 4404942036933073584L;
-//
-// IElement parentElement;
-// Map<String, String> substitutions;
-// Object component;
-// String suffix;
-// boolean hack;
-//
-// Initializer(IElement parentElement, Map<String, String> substitutions, Object component, String suffix, boolean hack) {
-// this.parentElement = parentElement;
-// this.substitutions = substitutions;
-// this.component = component;
-// this.suffix = suffix;
-// this.hack = hack;
-// }
-//
-// @Override
-// public void onElementActivated(IDiagram d, IElement e) {
-//
-// if(!hack) {
-//
-// hack = true;
-//
-// Point2D parentPos = ElementUtils.getPos(parentElement);
-// Point2D thisPos = ElementUtils.getPos(e);
-//
-// Move move = e.getElementClass().getSingleItem(Move.class);
-// move.moveTo(e, thisPos.getX() - parentPos.getX(), thisPos.getY() - parentPos.getY());
-//
-// }
-//
-// }
-// @Override
-// public void onElementCreated(IElement e) {
-// if(parentElement != null) e.setHint(ElementHints.KEY_PARENT_ELEMENT, parentElement);
-// if(substitutions != null) e.setHint(KEY_MONITOR_SUBSTITUTIONS, substitutions);
-// if(component != null) e.setHint(KEY_MONITOR_COMPONENT, component);
-// if(suffix != null) e.setHint(KEY_MONITOR_SUFFIX, suffix);
-//
-// e.setHint(KEY_DIRECTION, 0.0);
-// e.setHint(KEY_NUMBER_FORMAT, DEFAULT_NUMBER_FORMAT);
-// //e.setHint(KEY_HORIZONTAL_ALIGN, Alignment.LEADING);
-// //e.setHint(KEY_VERTICAL_ALIGN, Alignment.LEADING);
-// }
-// @Override
-// public void onElementDeactivated(IDiagram d, IElement e) {
-// }
-// @Override
-// public void onElementDestroyed(IElement e) {
-// }
-// };
-//
-// static String finalText(IElement e) {
-// String text = e.getElementClass().getSingleItem(Text.class).getText(e);
-// if (text == null)
-// return null;
-// return substitute(text, e);
-// }
-//
-// public static String editText(IElement e) {
-// return substitute("#v1", e);
-// }
-//
-// private static String formValue(IElement e) {
-// // TODO: consider using substitute
-// Map<String, String> substitutions = e.getHint(KEY_MONITOR_SUBSTITUTIONS);
-// if (substitutions != null) {
-// String value = substitutions.get("#v1");
-// if (substitutions.containsKey("#u1") && substitutions.get("#u1").length() > 0) {
-// value += " " + substitutions.get("#u1");
-// }
-// return value;
-// }
-// return null;
-// }
-//
-// static String substitute(String text, IElement e) {
-// Map<String, String> substitutions = e.getHint(KEY_MONITOR_SUBSTITUTIONS);
-// return substitute(text, substitutions);
-// }
-//
-// static String substitute(String text, Map<String, String> substitutions) {
-// if (substitutions != null) {
-// // TODO: slow as hell
-// for(Map.Entry<String, String> entry : substitutions.entrySet()) {
-// if (entry.getValue() != null) {
-// text = text.replace(entry.getKey(), entry.getValue());
-// } else {
-// text = text.replace(entry.getKey(), "<null>");
-// }
-// }
-// }
-// return text;
-// }
-//
-// public static void update(IElement e) {
-// MonitorSGNode node = e.getElementClass().getSingleItem(MonitorSGNode.class);
-// node.update(e);
-// }
-//
-// public static void cleanup(IElement e) {
-// MonitorSGNode node = e.getElementClass().getSingleItem(MonitorSGNode.class);
-// node.cleanup(e);
-// }
-//
-// static final Rectangle2D DEFAULT_BOX = new Rectangle2D.Double(0, 0, 0, 0);
-//
-// static Shape createMonitor(IElement e) {
-// Alignment hAlign = getHorizontalAlignment(e);
-// Alignment vAlign = getVerticalAlignment(e);
-// double hMargin = getHorizontalMargin(e);
-// double vMargin = getVerticalMargin(e);
-//
-// String text = finalText(e);
-// if(text == null) {
-// return align(hMargin, vMargin, hAlign, vAlign, DEFAULT_BOX);
-// }
-//
-// Graphics2D g = e.getHint(KEY_MONITOR_GC);
-// if(g == null) {
-// return align(hMargin, vMargin, hAlign, vAlign, DEFAULT_BOX);
-// }
-//
-// Font f = getFont(e);
-// FontMetrics fm = g.getFontMetrics(f);
-// Rectangle2D rect = fm.getStringBounds(text, g);
-//
-// return align(hMargin, vMargin, hAlign, vAlign, rect);
-// }
-//
-// static Shape align(double hMargin, double vMargin, Alignment hAlign, Alignment vAlign, Rectangle2D rect) {
-// //System.out.println("align: " + hMargin + ", " + vMargin + ", " + hAlign + ", " + vAlign + ": " + rect);
-// double tx = align(hMargin, hAlign, rect.getMinX(), rect.getMaxX());
-// double ty = align(vMargin, vAlign, rect.getMinY(), rect.getMaxY());
-// //System.out.println(" translate: " + tx + " " + ty);
-// double nw = rect.getWidth() + 2*hMargin;
-// double nh = rect.getHeight() + 2*vMargin;
-// return makePath(tx + rect.getMinX(), ty + rect.getMinY(), nw, nh);
-// }
-//
-// static double align(double margin, Alignment align, double min, double max) {
-// double s = max - min;
-// switch (align) {
-// case LEADING:
-// return -min;
-// case TRAILING:
-// return -s - 2 * margin - min;
-// case CENTER:
-// return -0.5 * s - margin - min;
-// default:
-// return 0;
-// }
-// }
-//
-// static Path2D makePath(double x, double y, double w, double h) {
-// Path2D path = new Path2D.Double();
-// path.moveTo(x, y);
-// path.lineTo(x+w, y);
-// path.lineTo(x+w, y+h);
-// path.lineTo(x, y+h);
-// path.closePath();
-// return path;
-// }
-//
-// public static final Shape BOX_SHAPE = new Rectangle(-1, -1, 2, 2);
-//
-// public static class MonitorSGNode implements SceneGraph, InternalSize, Outline {
-// private static final long serialVersionUID = -106278359626957687L;
-//
-// static final MonitorSGNode INSTANCE = new MonitorSGNode();
-//
-// @Override
-// public void init(final IElement e, final G2DParentNode parent) {
-// // Create node if it doesn't exist yet
-// MonitorNode node = (MonitorNode)e.getHint(KEY_SG_NODE);
-// if(node == null || node.getBounds() == null || node.getParent() != parent) {
-// node = parent.addNode(ElementUtils.generateNodeId(e), MonitorNode.class);
-// e.setHint(KEY_SG_NODE, node);
-//
-// node.setActionListener(new ActionListener() {
-// @Override
-// public void actionPerformed(ActionEvent event) {
-// TextEditor editor = e.getElementClass().getAtMostOneItemOfClass(TextEditor.class);
-// if (editor != null) {
-// Modifier modifier = editor.getModifier(e);
-// if (modifier != null) {
-// String newValue = event.getActionCommand();
-// String error = modifier.isValid(e, newValue);
-//
-// if (error == null) {
-// // Only modify if the modification was not
-// // cancelled and the value is valid.
-// modifier.modify(e, newValue);
-// } else {
-// // TODO: show error somehow, possibly through status bar
-//
-// // Make sure that the monitor content gets
-// // reset to its previous value.
-// MonitorNode node = e.getHint(KEY_SG_NODE);
-// if (node != null)
-// node.setText(formValue(e));
-// }
-// }
-// }
-//
-//// final Text t = e.getElementClass().getAtMostOneItemOfClass(Text.class);
-//// t.setText(e, event.getActionCommand()); // FIXME
-// }});
-// node.setSize(50, 22);
-// Double border_width = (Double)e.getHint(KEY_BORDER_WIDTH);
-// if(border_width == null) border_width = 0.1;
-//
-// node.setBorderWidth(border_width);
-//
-// Rectangle2D bounds = (Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS);
-// if(bounds != null) node.setBounds(bounds);
-// }
-// update(e);
-// }
-//
-// public void update(IElement e) {
-// String value = null;
-//
-// final Text t = e.getElementClass().getAtMostOneItemOfClass(Text.class);
-// assert(t != null);
-//
-// value = formValue(e);
-//
-// MonitorNode node = (MonitorNode) e.getHint(KEY_SG_NODE);
-// if (node != null && value != null) {
-// node.setText(value);
-// Object component = e.getHint(KEY_MONITOR_COMPONENT);
-// if (component != null) {
-// node.setEditable(true);
-// } else {
-// node.setEditable(false);
-// }
-//
-// // FIXME: set only if changed .. (but quickfix is not to clone)
-// Font font = ElementUtils.getTextFont(e);
-// if (node.getFont() != font) { // Don't update if we have a same object
-// node.setFont(font);
-// }
-// Color color = ElementUtils.getTextColor(e);
-// node.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
-// String tt = (String) e.getHint(KEY_TOOLTIP_TEXT);
-// if (tt != null)
-// node.setToolTipText(new String(tt));
-// }
-// }
-//
-// @Override
-// public void cleanup(IElement e) {
-// MonitorNode node = (MonitorNode)e.removeHint(KEY_SG_NODE);
-// if (node != null)
-// node.remove();
-// }
-//
-// @Override
-// public Rectangle2D getBounds(IElement e, Rectangle2D size) {
-// Rectangle2D shape = new Rectangle2D.Double(0, 0, 0, 0);
-//
-// MonitorNode node = (MonitorNode)e.getHint(KEY_SG_NODE);
-// if(node != null && node.getBounds() != null) {
-// shape = node.getBounds().getBounds2D();
-// }
-//
-// if(size != null) size.setRect(shape);
-// return shape;
-// }
-//
-// @Override
-// public Shape getElementShape(IElement e) {
-// Shape shape = new Rectangle2D.Double(0, 0, 0, 0);
-//
-// MonitorNode node = (MonitorNode)e.getHint(KEY_SG_NODE);
-// if(node != null && node.getBounds() != null) {
-// shape = node.getBounds();
-// }
-//
-// return shape;
-// }
-//
-// }
-//
-// public static class Transformer implements Transform, Move, Rotate, Scale, LifeCycle {
-//
-// private static final long serialVersionUID = -3704887325602085677L;
-//
-// public static final Transformer INSTANCE = new Transformer(null);
-//
-// Double aspectRatio;
-//
-// public Transformer() {
-// this(null);
-// }
-//
-// public Transformer(Double aspectRatio) {
-// this.aspectRatio = aspectRatio;
-// }
-//
-// @Override
-// public Double getFixedAspectRatio(IElement e) {
-// return aspectRatio;
-// }
-//
-// @Override
-// public Point2D getScale(IElement e) {
-// AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
-// return _getScale(at);
-// }
-//
-// @Override
-// public void setScale(IElement e, Point2D newScale) {
-// // Doesn't work for monitors.
-// Point2D oldScale = getScale(e);
-// double sx = newScale.getX() / oldScale.getX();
-// double sy = newScale.getY() / oldScale.getY();
-// AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
-// at = new AffineTransform(at);
-// at.scale(sx, sy);
-// e.setHint(ElementHints.KEY_TRANSFORM, at);
-// }
-//
-// @Override
-// public Point2D getMaximumScale(IElement e) {
-// return null;
-// }
-//
-// @Override
-// public Point2D getMinimumScale(IElement e) {
-// return null;
-// }
-//
-// private static Point2D _getScale(AffineTransform at) {
-// double m00 = at.getScaleX();
-// double m11 = at.getScaleY();
-// double m10 = at.getShearY();
-// double m01 = at.getShearX();
-// // Project unit vector to canvas
-// double sx = Math.sqrt(m00 * m00 + m10 * m10);
-// double sy = Math.sqrt(m01 * m01 + m11 * m11);
-// return new Point2D.Double(sx, sy);
-// }
-//
-// @Override
-// public void rotate(IElement e, double theta, Point2D origin) {
-// if (Double.isNaN(theta)) return;
-// theta = Math.toDegrees(theta);
-// Double angle = e.getHint(KEY_DIRECTION);
-// double newAngle = angle != null ? angle+theta : theta;
-// newAngle = Math.IEEEremainder(newAngle, 360.0);
-// e.setHint(KEY_DIRECTION, newAngle);
-// }
-//
-// @Override
-// public double getAngle(IElement e) {
-// Double angle = e.getHint(KEY_DIRECTION);
-// return angle != null ? Math.toRadians(angle) : 0;
-// }
-//
-// @Override
-// public Point2D getPosition(IElement e) {
-// AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
-// Point2D p = new Point2D.Double(at.getTranslateX(), at.getTranslateY());
-// return p;
-// }
-//
-// @Override
-// public void moveTo(IElement e, double x, double y) {
-// AffineTransform origAt = e.getHint(ElementHints.KEY_TRANSFORM);
-// double oldX = origAt.getTranslateX();
-// double oldY = origAt.getTranslateY();
-// AffineTransform move = AffineTransform.getTranslateInstance(x-oldX, y-oldY);
-// AffineTransform at2 = new AffineTransform(origAt);
-// at2.preConcatenate(move);
-// e.setHint(ElementHints.KEY_TRANSFORM, at2);
-// }
-//
-// @Override
-// public AffineTransform getTransform(IElement e) {
-// AffineTransform at = e.getHint(ElementHints.KEY_TRANSFORM);
-//
-// IElement parentElement = e.getHint(ElementHints.KEY_PARENT_ELEMENT);
-// if (parentElement == null)
-// return at;
-//
-// Transform parentTransform = parentElement.getElementClass().getSingleItem(Transform.class);
-// assert(parentTransform!=null);
-//
-// AffineTransform result = (AffineTransform)at.clone();
-// result.preConcatenate(parentTransform.getTransform(parentElement));
-//
-// return result;
-// }
-//
-// @Override
-// public void setTransform(IElement e, AffineTransform at) {
-// e.setHint(ElementHints.KEY_TRANSFORM, at.clone());
-// }
-//
-// @Override
-// public void onElementActivated(IDiagram d, IElement e) {
-// }
-//
-// @Override
-// public void onElementCreated(IElement e) {
-// e.setHint(ElementHints.KEY_TRANSFORM, new AffineTransform());
-// }
-//
-// @Override
-// public void onElementDeactivated(IDiagram d, IElement e) {
-// }
-//
-// @Override
-// public void onElementDestroyed(IElement e) {
-//// List<SceneGraph> nodeHandlers = e.getElementClass().getItemsByClass(SceneGraph.class);
-//// for(SceneGraph n : nodeHandlers) {
-//// System.out.println("element gone:"+e);
-//// n.cleanup(e);
-//// }
-// }
-// }
-//
-// static double getOrientationDelta(IElement e, AffineTransform tr) {
-// Double angle = e.getHint(KEY_DIRECTION);
-// if (angle == null || Double.isNaN(angle))
-// return Double.NaN;
-// double angrad = Math.toRadians(angle);
-//
-// Vector2d forcedAxis = new Vector2d(Math.cos(angrad), Math.sin(angrad));
-// Vector2d x = new Vector2d(tr.getScaleX(), tr.getShearX());
-// forcedAxis.normalize();
-// x.normalize();
-// double cosa = forcedAxis.dot(x);
-// double delta = Math.acos(cosa);
-// return delta;
-// }
-//
-// static class MonitorImageFactory implements IFactory<Image> {
-// private double staticScaleX = 1, staticScaleY = 1;
-//
-// public MonitorImageFactory(double staticScaleX, double staticScaleY) {
-// this.staticScaleX = staticScaleX;
-// this.staticScaleY = staticScaleY;
-// }
-//
-// @Override
-// public Image get() throws ProvisionException {
-// return new AbstractImage() {
-// Shape path = align(DEFAULT_HORIZONTAL_MARGIN, DEFAULT_VERTICAL_MARGIN, DEFAULT_HORIZONTAL_ALIGN, DEFAULT_VERTICAL_ALIGN,
-// new Rectangle2D.Double(0, 0, 50*staticScaleX, 22*staticScaleY));
-//
-// @Override
-// public Rectangle2D getBounds() {
-// return path.getBounds2D();
-// }
-//
-// @Override
-// public EnumSet<Feature> getFeatures() {
-// return EnumSet.of(Feature.Vector);
-// }
-//
-// @Override
-// public Shape getOutline() {
-// return path;
-// }
-//
-// @Override
-// public Node init(G2DParentNode parent) {
-// MonitorNode node = parent.getOrCreateNode(""+hashCode(), MonitorNode.class);
-// node.setText("");
-// node.setSize(50, 22);
-// node.setBorderWidth(1);
-// node.setText("Drop Me");
-// node.setTransform(AffineTransform.getScaleInstance(staticScaleX, staticScaleY));
-// return node;
-// }
-// };
-// }
-// }
-//
-// static final IProvider<Image> MONITOR_IMAGE =
-// ProviderUtils.reference(
-// ProviderUtils.cache(
-// ProviderUtils.rasterize(
-// new MonitorImageFactory(0.5, 0.5)
-// )));
-//
-// static final StaticSymbol MONITOR_SYMBOL = new StaticSymbolImpl( MONITOR_IMAGE.get() );
-//
-// static final FillColor FILL_COLOR = new FillColorImpl(DEFAULT_FILL_COLOR);
-//
-// public static final ElementClass MONITOR_CLASS =
-// ElementClass.compile(
-// MonitorHandlerImpl.INSTANCE,
-// Transformer.INSTANCE,
-// BorderColorImpl.BLACK,
-// FILL_COLOR,
-// MonitorSGNode.INSTANCE,
-// TextImpl.INSTANCE,
-// TextEditorImpl.INSTANCE,
-// TextFontImpl.DEFAULT,
-// TextColorImpl.BLACK,
-// SimpleElementLayers.INSTANCE,
-// MONITOR_SYMBOL
-// );
-//
-// // staticScale{X,Y} define the scale of the static monitor image
-// public static ElementClass create(IElement parentElement, Map<String, String> substitutions, Object component, String suffix, double staticScaleX, double staticScaleY, ElementHandler... extraHandlers) {
-// // Bit of a hack to be able to define the scale
-// IProvider<Image> staticMonitorSymbolProvider = ProviderUtils.reference(
-// ProviderUtils.cache(
-// ProviderUtils
-// .rasterize(
-// new MonitorImageFactory(staticScaleX, staticScaleY))));
-// StaticSymbol staticMonitorSymbol = new StaticSymbolImpl( staticMonitorSymbolProvider.get() );
-// return ElementClass.compile(
-// new Initializer(parentElement, substitutions, component, suffix, parentElement != null ? false : true),
-// MonitorHandlerImpl.INSTANCE,
-// Transformer.INSTANCE,
-// BorderColorImpl.BLACK,
-// FILL_COLOR,
-// MonitorSGNode.INSTANCE,
-// TextImpl.INSTANCE,
-// TextEditorImpl.INSTANCE,
-// TextFontImpl.DEFAULT,
-// TextColorImpl.BLACK,
-// SimpleElementLayers.INSTANCE,
-// staticMonitorSymbol
-// ).newClassWith(extraHandlers);
-// }
-//
-//}
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import javax.vecmath.Vector2d;
-import javax.vecmath.Vector3d;
-
+import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.diagram.IDiagram;
import org.simantics.g2d.element.ElementHints;
public static final RotatorHandler INSTANCE = new RotatorHandler();
- public static final double STRAY_DISTANCE = 1000;
+ public static final double STRAY_DISTANCE = 1000;
public double initial_friction = 0.20;
public double initial_grab_friction = 0.99;
/** Angular velocity, canvas specific variable */
public static final Key KEY_ANG_VEL = new KeyOf(Double.class);
/** Minimum number of pointers */
- public static final Key KEY_MIN_POINTERS = new KeyOf(Integer.class);
- public static final Key KEY_GRAB_FRICTION = new KeyOf(Double.class);
+ public static final Key KEY_MIN_POINTERS = new KeyOf(Integer.class);
+ public static final Key KEY_GRAB_FRICTION = new KeyOf(Double.class);
public static final Key KEY_FRICTION = new KeyOf(Double.class);
public static final Key KEY_FACTOR = new KeyOf(Double.class);
@Override
protected void onDrag(GrabInfo gi, ICanvasContext ctx) {
IElement e = gi.e;
- Point2D origo = getOrigo(e, null);
+ Point2D origo = getOrigo(e, null);
Point2D prevPos = gi.prevPosElement;
Point2D p = gi.dragPosElement;
- // ---- Wheel is held! ----
+ // ---- Wheel is held! ----
// position vector 0
- Vector2d p0 = new Vector2d(prevPos.getX(), prevPos.getY());
+ Vector2D p0 = new Vector2D(prevPos.getX(), prevPos.getY());
// position vector 1
- Vector2d p1 = new Vector2d(p.getX(), p.getY());
+ Vector2D p1 = new Vector2D(p.getX(), p.getY());
// motion vector
- Vector2d f = new Vector2d(p1);
- f.sub(p0);
+ Vector2D f = p1.subtract(p0);
// no movement
- if (f.length()==0) return;
+ if (f.getNormSq()==0) return;
// -- We are holding the wheel and we have moved the pointer --
// vector from origo to mouse
- Vector2d odp0 = new Vector2d(p0.x - origo.getX(), p0.y - origo.getY());
- Vector2d odp1 = new Vector2d(p1.x - origo.getX(), p1.y - origo.getY());
+ Vector2D odp0 = new Vector2D(p0.getX() - origo.getX(), p0.getY() - origo.getY());
+ Vector2D odp1 = new Vector2D(p1.getX() - origo.getX(), p1.getY() - origo.getY());
// convert motion into tangential and normal vectors
// normal vector of the motion
- Vector2d fn = new Vector2d(odp0);
- fn.scale( f.dot(odp0) / odp0.lengthSquared() );
+ Vector2D fn = odp0.scalarMultiply( f.dotProduct(odp0) / odp0.getNormSq() );
// tangential vector of the motion
- Vector2d ft = new Vector2d(f);
- ft.sub(fn);
+ Vector2D ft = f.subtract(fn);
// momentum
- Vector3d r = new Vector3d(odp0.x, odp0.y, 0);
- Vector3d F = new Vector3d(ft.x, ft.y, 0);
- Vector3d M = new Vector3d();
- M.cross(r, F);
+ Vector3D r = new Vector3D(odp0.getX(), odp0.getY(), 0);
+ Vector3D F = new Vector3D(ft.getX(), ft.getY(), 0);
+ Vector3D M = r.crossProduct(F);
if (!isGrabbed(e, ctx)) return;
// Turn the wheel
- double deltaAngle = odp0.angle(odp1);
- if (M.z<0) deltaAngle *= -1;
+ double deltaAngle = Vector2D.angle(odp0, odp1);
+ if (M.getZ()<0) deltaAngle *= -1;
double deltaAngularVelocity = deltaAngle * 20;
setAngVel(e, getAngVel(e)+deltaAngularVelocity);
deltaAngle *= 0.297;
- modifyValue(e, ctx, deltaAngle);
+ modifyValue(e, ctx, deltaAngle);
}
@Override
double dt = ((double)deltaTime)/1000;
angVel *= Math.pow(1-f, dt);
setAngVel(e, angVel);
- ctx.getContentContext().setDirty();
+ ctx.getContentContext().setDirty();
}
@Override
public void setAngVel(IElement e, double value)
{
- e.setHint(KEY_ANG_VEL, value);
+ e.setHint(KEY_ANG_VEL, value);
}
public boolean isGrabbed(IElement e, ICanvasContext ctx) {
- return (getGrabCount(e, ctx)>=getMinPointers(e)) || !isEnabled(e);
+ return (getGrabCount(e, ctx)>=getMinPointers(e)) || !isEnabled(e);
}
public boolean isMoving(IElement e) {
public boolean isMoveable(IElement e) {
return true;
- }
+ }
-
-
}
*/
public class WheelClass {
- public static final ElementClass WHEEL =
- ElementClass.compile(
- // Pick missing
- DefaultTransform.INSTANCE,
- new RotatorHandler(),
- new PaintableSymbolHandler(DefaultImages.WHEEL),
- Stateful.ENABLED_BY_DEFAULT
- );
-
+ public static final ElementClass WHEEL =
+ ElementClass.compile(
+ // Pick missing
+ DefaultTransform.INSTANCE,
+ new RotatorHandler(),
+ new PaintableSymbolHandler(DefaultImages.WHEEL),
+ Stateful.ENABLED_BY_DEFAULT
+ );
-
}
--- /dev/null
+package org.simantics.graph.compiler.internal.resourceFiles;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+public class FilterCRWriter extends FilterWriter {
+
+ public FilterCRWriter(Writer out) {
+ super(out);
+ }
+
+ @Override
+ public void write(int c) throws IOException {
+ if(c != '\r')
+ out.write(c);
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ int begin = 0;
+ for(int i=0;i<len;++i) {
+ if(cbuf[off+i] == '\r') {
+ if(i > begin)
+ write(cbuf, off+begin, i-begin);
+ begin = i+1;
+ }
+ }
+ if(len > begin)
+ write(cbuf, off+begin, len-begin);
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ int begin = 0;
+ for(int i=0;i<len;++i) {
+ if(str.charAt(off+i) == '\r') {
+ if(i > begin)
+ write(str, off+begin, i-begin);
+ begin = i+1;
+ }
+ }
+ if(len > begin)
+ write(str, off+begin, len-begin);
+ }
+
+}
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
+import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import freemarker.template.Template;
public class ResourceFile implements IResourceFile {
+ private final static Charset UTF8 = Charset.forName("UTF-8");
+
String packageName;
String className;
List<ResourceRef> resources;
@Override
public InputStream getContent() {
StringWriter writer = new StringWriter();
- write(writer);
- return new ByteArrayInputStream(writer.toString().getBytes());
+ write(String.format("%n").length() == 1 ? new FilterCRWriter(writer) : writer);
+ return new ByteArrayInputStream(writer.toString().getBytes(UTF8));
}
/* (non-Javadoc)
}
public static void main(String[] args) {
- ResourceRef Foo = new ResourceRef("Foo", "http://www.dsf.sdf/Foo");
+ /*ResourceRef Foo = new ResourceRef("Foo", "http://www.dsf.sdf/Foo");
ResourceRef Bar = new ResourceRef("Foo", "http://www.dsf.sdf/Bar");
Bar.deprecated = true;
new ResourceFile("org.simantics.graph", "Testi", Arrays.<ResourceRef>asList(
Foo, Bar
- )).write(new OutputStreamWriter(System.out));
+ )).write(new OutputStreamWriter(System.out));*/
+ System.out.println(String.format("%n").length());
}
}
}
static {
+ // IMPORTANT NOTICE:
+ // DO NOT alter the order of these definitions in any way
+ // unless you deliberately want to make the system incompatible
+ // with databases that have been created before changing these.
addLayer0Builtin("InstanceOf");
addLayer0Builtin("Inherits");
addLayer0Builtin("SubrelationOf");
addLayer0Builtin("HasPredicateInverse");
addLayer0Builtin("HasObject");
- addBuiltin("http://Projects");
+ // #7016: This bogus URI replaces the builtin entry
+ // that was originally http://Projects.
+ //
+ // addBuiltin("http://Projects") was removed because its existence
+ // resulted in a non-functioning URI space because:
+ //
+ // 1. http://Projects was added as a "built-in resource" when the database
+ // is first initialized which means that ReadGraph.getResource("http://Projects")
+ // would succeed even when the resource was not yet properly imported
+ // from the project ontology.
+ //
+ // 2. When the project ontology is imported, a new resource is
+ // created to represent http://Projects instead of using the existing
+ // uninitialized "built-in resource". The L0.ExternalEntity changes made
+ // to the standard transferable graph import in this patch caused the
+ // code to find the built-in resource for "http://Projects" and think
+ // that it has to be a resource that's already properly initialized.
+ // This led to the TG import not initializing the resource at all.
+ // Previously there was a bug here as well but it was hidden by the fact
+ // that the system would import the actual/new "http://Projects"
+ // resource from the ontology anyway. This effectively left the
+ // uninitialized built-in resource just hanging in the database as
+ // trash.
+ //addBuiltin("http://Projects");
+ addBuiltin("75e23fb39121b4b37cf2e6a26ccb34c52f77522d-do-not-remove");
addBuiltin("http:/");
+ addLayer0Builtin("ExternalEntity");
}
public static void initializeBuiltins(Session session) throws DatabaseException {
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semamtum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.graph.db;
+
+import java.util.Set;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class ImportResult {
+
+ /**
+ * This lists externals that the import was missing and has created in the
+ * database as L0.ExternalEntity place-holders for now.
+ */
+ public final Set<String> missingExternals;
+
+ public ImportResult(Set<String> missingExternals) {
+ this.missingExternals = missingExternals;
+ }
+
+ public boolean hasMissingExternals() {
+ return !missingExternals.isEmpty();
+ }
+
+}
/*******************************************************************************
- * Copyright (c) 2012, 2016 Association for Decentralized Information Management
+ * Copyright (c) 2012, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
- * Semantum Oy
+ * Semantum Oy - e.g. #7016
*******************************************************************************/
package org.simantics.graph.db;
import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.DataOutputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.simantics.databoard.binding.mutable.Variant;
import org.simantics.databoard.serialization.Serializer;
import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.URIStringUtils;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.Session;
import org.simantics.db.service.ClusterBuilderFactory;
import org.simantics.db.service.ClusteringSupport;
import org.simantics.db.service.SerialisationSupport;
+import org.simantics.db.service.XSupport;
import org.simantics.graph.db.TransferableGraphSource.TransferableGraphSourceProcedure;
import org.simantics.graph.db.TransferableGraphSource.TransferableGraphSourceValueProcedure;
import org.simantics.graph.representation.Extensions;
import org.simantics.graph.representation.TransferableGraphUtils;
import org.simantics.graph.utils.TGResourceUtil;
import org.simantics.graph.utils.TGResourceUtil.LongAdapter;
+import org.simantics.utils.datastructures.Pair;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
public class StreamingTransferableGraphImportProcess implements TransferableGraphImporter {
-
- public static String LOG_FILE = "transferableGraphs.log";
- final static private boolean LOG = false;
-
- static DataOutput log;
- static {
-
- if (LOG) {
-
- try {
- FileOutputStream stream = new FileOutputStream(LOG_FILE);
- log = new DataOutputStream(stream);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- }
-
- private static void log(String line) {
- if (LOG) {
- try {
- log.writeUTF(line + "\n");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
+ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StreamingTransferableGraphImportProcess.class);
Resource indexRoot;
TransferableGraphSource tg;
IImportAdvisor2 advisor;
ClusterBuilder2 builder;
final TGResourceUtil resourceUtil = new TGResourceUtil();
-
+
int[] handles;
-
- Set<String> missingExternals = new HashSet<String>();
-
+
+ Map<String,Integer> allMissingExternals = new HashMap<>();
+ Set<String> missingExternals = new HashSet<>();
+ Map<String,Resource> resolvedParents = new HashMap<>();
+ TIntObjectHashMap<Resource> existingInternalMap = new TIntObjectHashMap<>();
+
int resourceCount;
Identity[] identities;
TreeMap<String, Variant> extensions;
-
+
// Builtins
Resource RootLibrary;
Resource String;
+ Resource ExternalEntity;
Resource Library;
-
+
Resource InstanceOf;
Resource ConsistsOf;
Resource PartOf;
Resource HasName;
Resource NameOf;
-
+
public StreamingTransferableGraphImportProcess(Session session, VirtualGraph vg, TransferableGraphSource tg, IImportAdvisor2 advisor) {
this.tg = tg;
this.vg = vg;
this.advisor = advisor;
}
-
+
public void readIdentities(ReadGraph g) throws Exception {
extensions = tg.getExtensions();
resourceCount = tg.getResourceCount();
}
});
}
-
+
public void findBuiltins(WriteOnlyGraph g) throws DatabaseException {
RootLibrary = g.getBuiltin("http:/");
String = g.getBuiltin(CoreInitialization.LAYER0 + "String");
PartOf = g.getBuiltin(CoreInitialization.LAYER0 + "PartOf");
HasName = g.getBuiltin(CoreInitialization.LAYER0 + "HasName");
NameOf = g.getBuiltin(CoreInitialization.LAYER0 + "NameOf");
+ ExternalEntity = g.getBuiltin(CoreInitialization.LAYER0 + "ExternalEntity");
}
-
+
public void findBuiltins(ReadGraph g) throws DatabaseException {
RootLibrary = g.getBuiltin("http:/");
String = g.getBuiltin(CoreInitialization.LAYER0 + "String");
PartOf = g.getBuiltin(CoreInitialization.LAYER0 + "PartOf");
HasName = g.getBuiltin(CoreInitialization.LAYER0 + "HasName");
NameOf = g.getBuiltin(CoreInitialization.LAYER0 + "NameOf");
+ ExternalEntity = g.getBuiltin(CoreInitialization.LAYER0 + "ExternalEntity");
}
-// /* Preparation that is used when the core is empty.
-// */
-// void initialPrepare(WriteOnlyGraph graph) throws DatabaseException {
-// findBuiltins(graph);
-//
-// resources = new Resource[tg.resourceCount];
-//
-// int Root = -1;
-// int SimanticsDomain = -1;
-// int Layer0 = -1;
-//
-// for(Identity identity : tg.identities) {
-// if(identity.definition instanceof Internal) {
-// Internal def = (Internal)identity.definition;
-// Resource res = null;
-// if(def.parent == Layer0) {
-// try {
-// res = graph.getBuiltin(CoreInitialization.LAYER0 + def.name);
-// } catch(ResourceNotFoundException e) {
-// }
-// }
-// else if(def.parent == SimanticsDomain) {
-// if(def.name.equals("Layer0-1.0"))
-// Layer0 = identity.resource;
-// }
-// else if(def.parent == Root) {
-// if(def.name.equals("www.simantics.org"))
-// SimanticsDomain = identity.resource;
-// }
-//
-// if(res == null)
-// res = createChild(graph, resources[def.parent], def.name);
-// else
-// createChild(graph, res, resources[def.parent], def.name);
-// resources[identity.resource] = res;
-// }
-// else if(identity.definition instanceof Root) {
-// Root = identity.resource;
-// resources[identity.resource] = RootLibrary;
-// }
-// }
-// }
-
- void addMissing(String external) {
- Set<String> removals = new HashSet<String>();
+ void addMissing(int handleIndex, String external) {
+ allMissingExternals.put(external, handleIndex);
+ Set<String> removals = new HashSet<>();
for(String ext : missingExternals) if(ext.startsWith(external)) return;
for(String ext : missingExternals) if(external.startsWith(ext)) removals.add(ext);
missingExternals.removeAll(removals);
missingExternals.add(external);
}
-
+
void prepare(ReadGraph graph) throws Exception {
Resource target = advisor.getTarget();
ClusterBuilderFactory factory = graph.getService(ClusterBuilderFactory.class);
ClusterBuilder2 builder = factory.create(vg, false);
- this.handles = new int[resourceCount];
+ this.handles = new int[resourceCount];
+ TIntObjectMap<Identity> identityMap = TransferableGraphUtils.mapIdentities(identities);
for(Identity identity : identities) {
IdentityDefinition definition = identity.definition;
Resource parent = handle != 0 ? builder.resource(handle) : null;
// TODO: escape should be removed when names become well-behaving
if(parent != null) {
+ resolvedParents.put(graph.getURI(parent), parent);
Map<String,Resource> childMap = graph
.syncRequest(new UnescapedChildMapOfResource(parent),
- new TransientCacheAsyncListener<Map<String, Resource>>());
+ TransientCacheAsyncListener.instance());
Resource child = childMap.get(def.name);
if(child == null) {
- addMissing(graph.getURI(parent) + "/" + def.name);
+ addMissing(identity.resource, graph.getURI(parent) + "/" + def.name);
} else {
handles[identity.resource] = builder.handle(child);
}
} else {
- addMissing(TransferableGraphUtils.getURI(resourceCount, identities, def.parent) + "/" + def.name);
+ addMissing(identity.resource, TransferableGraphUtils.getURI(resourceCount, identityMap, def.parent) + "/" + def.name);
}
}
}
}
else if(definition instanceof Internal) {
- // Do not do anything for now
+ String uri = TransferableGraphUtils.getURI(resourceCount, identityMap, identity.resource);
+ Resource existing = graph.getPossibleResource(uri);
+ if(existing != null) {
+ existingInternalMap.put(identity.resource, existing);
+ }
}
else if(definition instanceof Root) {
Root root = (Root)definition;
}
}
- if(!missingExternals.isEmpty()) throw new MissingDependencyException(this);
+ //if(!missingExternals.isEmpty()) throw new MissingDependencyException(this);
}
graph.claim(child, HasName, NameOf, nameResource);
return child;
}
-
+
int[] getClustering() {
Variant v = extensions.get(Extensions.CLUSTERING);
if(v == null) return null;
boolean needTranslation(Datatype type) {
return resourceUtil.mayHaveResource(type);
}
-
+
void findClusterSet(WriteOnlyGraph graph, Resource rootLibrary, int[] clustering, int[] clusterSets, long[] clusters, int id) throws DatabaseException {
ClusteringSupport support = graph.getService(ClusteringSupport.class);
if(id == Extensions.ROOT_LIBRARY_CLUSTER_SET || id == Extensions.INDEX_ROOT_CLUSTER_SET) return;
}
}
}
-
+
+ void createMissing(final WriteOnlyGraph graph) throws Exception {
+
+ if(allMissingExternals.isEmpty()) return;
+
+ XSupport xs = graph.getService(XSupport.class);
+ Pair<Boolean,Boolean> serviceMode = xs.getServiceMode();
+ xs.setServiceMode(true, false);
+ try {
+ ArrayList<String> missing = new ArrayList<>(allMissingExternals.keySet());
+ Collections.sort(missing);
+ for(String uri : missing) {
+ String[] parts = URIStringUtils.splitURI(uri);
+
+ Resource parent = resolvedParents.get(parts[0]);
+ // TODO: proper exception message
+ if(parent == null) throw new IllegalStateException("!!");
+
+ Resource childResource = graph.newResource();
+ graph.claim(childResource, InstanceOf, null, ExternalEntity);
+
+ Resource nameResource = graph.newResource();
+ graph.claim(nameResource, InstanceOf, null, String);
+ graph.claimValue(nameResource, parts[1], WriteBindings.STRING);
+ graph.claim(childResource, HasName, NameOf, nameResource);
+
+ graph.claim(parent, ConsistsOf, PartOf, childResource);
+
+ resolvedParents.put(uri, childResource);
+
+ handles[allMissingExternals.get(uri)] = builder.handle(childResource);
+ }
+ } finally {
+ xs.setServiceMode(serviceMode.first, serviceMode.second);
+ }
+ }
+
void write(final WriteOnlyGraph graph) throws Exception {
final SerialisationSupport ss = graph.getService(SerialisationSupport.class);
-
+
ClusterBuilderFactory factory = graph.getService(ClusterBuilderFactory.class);
if(advisor instanceof IImportAdvisor2) {
boolean allowImmutable = ((IImportAdvisor2)advisor).allowImmutableModifications();
builder = factory.create(vg, false);
}
+ createMissing(graph);
+
final int[] handles = this.handles;
int[] clustering = getClustering();
}
else if(definition instanceof Internal) {
Internal def = (Internal)definition;
- if(handles[identity.resource] != 0)
- handles[identity.resource] = builder.handle(advisor.createChild(graph, this, builder.resource(handles[def.parent]), builder.resource(handles[identity.resource]), def.name));
- else
- handles[identity.resource] = builder.handle(advisor.createChild(graph, this, builder.resource(handles[def.parent]), null, def.name));
+
+ Resource external = existingInternalMap.get(identity.resource);
+ if(external != null) {
+ handles[identity.resource] = builder.handle(external);
+ } else {
+ if(handles[identity.resource] != 0)
+ handles[identity.resource] = builder.handle(advisor.createChild(graph, this, builder.resource(handles[def.parent]), builder.resource(handles[identity.resource]), def.name));
+ else
+ handles[identity.resource] = builder.handle(advisor.createChild(graph, this, builder.resource(handles[def.parent]), null, def.name));
+ }
+
}
else if(definition instanceof Root) {
});
tg.getValueCount();
-
+
class ValueProcedure extends InputStream implements TransferableGraphSourceValueProcedure {
private TGResourceUtil util = new TGResourceUtil();
try {
builder.appendValue(value);
} catch (DatabaseException e) {
- e.printStackTrace();
+ LOGGER.error("Failed to write value into database", e);
}
return value;
}
tg.forValues2(null, new ValueProcedure());
+ for(Resource r : existingInternalMap.valueCollection()) {
+ graph.deny(r, InstanceOf, null, ExternalEntity, null);
+ }
+
}
-
+
@Override
public long[] getResourceIds(SerialisationSupport serializer) throws DatabaseException {
final int count = handles.length;
import java.util.HashSet;
import java.util.TreeMap;
import java.util.UUID;
+import java.util.function.BiFunction;
import org.simantics.databoard.Accessors;
import org.simantics.databoard.Bindings;
import org.simantics.graph.representation.Identity;
import org.simantics.graph.representation.TransferableGraph1;
import org.simantics.graph.representation.Value;
-import org.simantics.utils.datastructures.BinaryFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
session.getService(SerialisationSupport.class));
}
- public static void importGraph1(Session session, final TransferableGraph1 tg, IImportAdvisor advisor, final BinaryFunction<Boolean, WriteOnlyGraph, TransferableGraphImportProcess> callback) throws DatabaseException, TransferableGraphException {
+ public static void importGraph1(Session session, final TransferableGraph1 tg, IImportAdvisor advisor, final BiFunction<WriteOnlyGraph, TransferableGraphImportProcess, Boolean> callback) throws DatabaseException, TransferableGraphException {
final TransferableGraphImportProcess process = new TransferableGraphImportProcess(tg,
advisor == null ? new ImportAdvisor() : advisor);
session.syncRequest(new ReadRequest() {
public void perform(WriteOnlyGraph graph) throws DatabaseException {
process.write(graph);
if(callback != null)
- callback.call(graph, process);
+ callback.apply(graph, process);
}
});
}
- public static void importGraph1(Session session, final TransferableGraphSource tg, IImportAdvisor advisor) throws Exception {
- importGraph1(session, tg, advisor, null);
+ public static ImportResult importGraph1(Session session, final TransferableGraphSource tg, IImportAdvisor advisor) throws Exception {
+ return importGraph1(session, tg, advisor, null);
}
- public static void importGraph1(Session session, final TransferableGraphSource tg, IImportAdvisor advisor, TGStatusMonitor monitor) throws DatabaseException {
- importGraph1(session, null, tg, advisor, monitor);
+ public static ImportResult importGraph1(Session session, final TransferableGraphSource tg, IImportAdvisor advisor, TGStatusMonitor monitor) throws DatabaseException {
+ return importGraph1(session, null, tg, advisor, monitor);
}
- public static void importGraph1(Session session, VirtualGraph vg, final TransferableGraphSource tg, IImportAdvisor advisor_, TGStatusMonitor monitor) throws DatabaseException {
+ public static ImportResult importGraph1(Session session, VirtualGraph vg, final TransferableGraphSource tg, IImportAdvisor advisor_, TGStatusMonitor monitor) throws DatabaseException {
final IImportAdvisor2 advisor = (advisor_ instanceof IImportAdvisor2) ? ((IImportAdvisor2)advisor_) : new WrapperAdvisor(advisor_);
}
}
});
+
+ return new ImportResult(process.missingExternals);
}
public static void importGraph1WithMonitor(Session session, final TransferableGraph1 tg, IImportAdvisor advisor_, TGStatusMonitor monitor) throws DatabaseException {
});
}
- public static void importGraph1WithChanges(Session session, final TransferableGraph1 tg, IImportAdvisor advisor, final BinaryFunction<Boolean, WriteGraph, TransferableGraphImportProcess> callback) throws DatabaseException, TransferableGraphException {
+ public static void importGraph1WithChanges(Session session, final TransferableGraph1 tg, IImportAdvisor advisor, final BiFunction<WriteGraph, TransferableGraphImportProcess, Boolean> callback) throws DatabaseException, TransferableGraphException {
final TransferableGraphImportProcess process = new TransferableGraphImportProcess(tg,
advisor == null ? new ImportAdvisor() : advisor);
session.syncRequest(new ReadRequest() {
comments.add("Imported transferable graph with " + tg.resourceCount + " resources");
graph.addMetadata(comments);
if(callback != null)
- callback.call(graph, process);
+ callback.apply(graph, process);
}
});
}
*******************************************************************************/
package org.simantics.graph.db.old;
+import java.util.function.BiFunction;
+
import org.simantics.db.ReadGraph;
import org.simantics.db.Session;
import org.simantics.db.WriteGraph;
import org.simantics.graph.db.ImportAdvisor;
import org.simantics.graph.db.TransferableGraphException;
import org.simantics.graph.representation.old.OldTransferableGraph1;
-import org.simantics.utils.datastructures.BinaryFunction;
public class OldTransferableGraphs {
- public static void importGraph1(Session session, final OldTransferableGraph1 tg, IImportAdvisor advisor, final BinaryFunction<Boolean, WriteOnlyGraph, OldTransferableGraphImportProcess1> callback) throws DatabaseException, TransferableGraphException {
+ public static void importGraph1(Session session, final OldTransferableGraph1 tg, IImportAdvisor advisor, final BiFunction<WriteOnlyGraph, OldTransferableGraphImportProcess1, Boolean> callback) throws DatabaseException, TransferableGraphException {
final OldTransferableGraphImportProcess1 process = new OldTransferableGraphImportProcess1(tg,
advisor == null ? new ImportAdvisor() : advisor);
session.syncRequest(new ReadRequest() {
public void perform(WriteOnlyGraph graph) throws DatabaseException {
process.write(graph);
if(callback != null)
- callback.call(graph, process);
+ callback.apply(graph, process);
}
});
}
package org.simantics.graph.refactoring;
import java.util.ArrayList;
+import java.util.Arrays;
+import org.simantics.databoard.util.URIStringUtils;
import org.simantics.graph.query.Path;
import org.simantics.graph.query.PathChild;
import org.simantics.graph.query.TransferableGraphConversion;
import org.simantics.graph.representation.TransferableGraphUtils;
import org.simantics.graph.representation.old.OldTransferableGraph1;
import org.simantics.graph.representation.old.OldValue1;
+import org.simantics.graph.store.GraphStore;
import org.simantics.graph.store.IdentityStore;
import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.set.hash.TIntHashSet;
public class GraphRefactoringUtils {
}
+ private static Identity recursePath(TransferableGraph1 tg, String path) {
+
+ Identity extId = TransferableGraphUtils.findExternal(tg, path);
+ if(extId != null) return extId;
+ if("http://".equals(path)) return TransferableGraphUtils.findRootWithName(tg, "");
+ String[] parts = URIStringUtils.splitURI(path);
+ Identity parentId = recursePath(tg, parts[0]);
+ tg.identities = Arrays.copyOf(tg.identities, tg.identities.length+1);
+ Identity childIdentity = new Identity(tg.resourceCount++, new External(parentId.resource, parts[1]));
+ tg.identities[tg.identities.length-1] = childIdentity;
+ return childIdentity;
+
+ }
+
public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {
Identity[] ids = tg.identities;
if(id.definition instanceof Root) {
Root ext = (Root)id.definition;
if(ext.name.startsWith("http://")) {
- String rootName = ext.name.substring(ext.name.lastIndexOf("/")+1);
- String path = ext.name.substring(0, ext.name.lastIndexOf("/"));
- Identity pathId = TransferableGraphUtils.findExternal(tg, path);
- System.err.println("GraphRefactoringUtils.rootName=" + rootName);
- System.err.println("GraphRefactoringUtils.path2=" + path);
- if(pathId == null) {
- if(!tryToFix) return;
- IdentityStore idStore = TransferableGraphConversion.extractIdentities(tg);
- idStore.createPathToId(UriUtils.uriToPath(path));
- tg.resourceCount = idStore.getResourceCount();
- tg.identities = idStore.toArray();
- fixOntologyRoot(tg, false);
- return;
- } else {
- id.definition = new Internal(pathId.resource, rootName);
- TIntArrayList stms = new TIntArrayList(tg.statements);
- Identity consistsOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
- Identity partOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/PartOf");
- stms.add(id.resource);
- stms.add(partOf.resource);
- stms.add(consistsOf.resource);
- stms.add(pathId.resource);
- tg.statements = stms.toArray();
- return;
- }
+
+ String[] parts = URIStringUtils.splitURI(ext.name);
+ Identity path = recursePath(tg, parts[0]);
+ id.definition = new Internal(path.resource, parts[1]);
+
+ GraphStore store = TransferableGraphConversion.convert(tg);
+ int rootId = store.identities.createPathToId(UriUtils.uriToPath(ext.name));
+ propagateNewMarks(store.identities, rootId);
+
+ TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
+
+ tg.resourceCount = tgNew.resourceCount;
+ tg.identities = tgNew.identities;
+ tg.values = tgNew.values;
+ tg.statements = tgNew.statements;
+
+ return;
}
}
}
}
+
+ private static void propagateNewMarks(IdentityStore identities, int resource) {
+ if(identities.markNew(resource)) {
+ for(int child : identities.getChildren(resource))
+ propagateNewMarks(identities, child);
+ }
+ }
public static void unfixIncorrectRoot(Identity[] ids) {
for(int i=0;i<ids.length;++i) {
--- /dev/null
+package org.simantics.graph.representation;
+
+import java.io.BufferedInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.TreeMap;
+
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.container.DataContainers;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.set.hash.TLongHashSet;
+
+/**
+ * @author Antti Villberg
+ * @since 1.24.0
+ */
+public class PrettyPrintTG extends TransferableGraphUtils {
+
+ int blankCounter = 0;
+
+ StringBuilder output = new StringBuilder();
+
+ static class ResourceInfo {
+ final boolean hasURI;
+ final String name;
+ final int resource;
+ boolean newResource = false;
+ int owner = 0;
+ int ownerPredicate = 0;
+ TIntArrayList owned = new TIntArrayList();
+ TIntArrayList statements = new TIntArrayList();
+ public ResourceInfo(boolean hasURI, String name, int resource) {
+ this.hasURI = hasURI;
+ this.name = name;
+ this.resource = resource;
+ }
+ }
+
+ TIntObjectHashMap<ResourceInfo> infos = new TIntObjectHashMap<>();
+
+ ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) {
+ String name = parentName + ".\"" + getName(parent) + "\"";
+ ResourceInfo info = new ResourceInfo(true, name, parent.resource);
+ infos.put(parent.resource, info);
+ for(Identity child : getChildren(graph, parent)) {
+ recurseURI(graph, child, name);
+ }
+ return info;
+ }
+
+ void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) {
+ TIntArrayList statements = getStatements(graph, resource);
+ for(int i=0;i<statements.size();i+=2) {
+ int object = statements.get(i+1);
+ Identity objectId = getIdentity(graph, object);
+ if(objectId != null) {
+ if(objectId.definition instanceof External) continue;
+ }
+ ResourceInfo existing = infos.get(object);
+ if(existing == null) {
+ existing = new ResourceInfo(false, "blank" + blankCounter++, object);
+ infos.put(object, existing);
+ todo.add(object);
+ }
+ }
+ }
+
+ void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
+ int resource = info.resource;
+ TIntArrayList statements = getStatements(graph, resource);
+ for(int i=0;i<statements.size();i+=2) {
+ int predicate = statements.get(i);
+ int object = statements.get(i+1);
+ ResourceInfo existing = infos.get(object);
+ if(existing == null) continue;
+ if(existing.owner == 0) {
+ existing.owner = resource;
+ existing.ownerPredicate = predicate;
+ //System.err.println("First owner " + info.name + " => " + predicateURI + " " + existing.name);
+ } else {
+ existing.owner = -1;
+ //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name);
+ }
+ }
+ info.statements = statements;
+ }
+
+ void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) {
+ Identity id = getIdentity(graph, info.resource);
+ if(id == null) return;
+ if(id.definition instanceof Internal) {
+ Identity instanceOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/InstanceOf");
+ Identity library = findExternal(graph, "http://www.simantics.org/Layer0-1.1/Library");
+ info.statements.add(instanceOf.resource);
+ info.statements.add(library.resource);
+ }
+ }
+
+ public static String getExternalURI(TransferableGraph1 tg, External ext) {
+ String name = ext.name;
+ if(name.contains(" ")) name = name.replace(" ", "_").replaceAll("@", "_");//name = "\"" + name + "\"";
+ int parentId = ext.parent;
+ if(parentId == 0) return ext.name;
+ else {
+ Identity id = getIdentity(tg, parentId);
+ if(id.definition instanceof External) {
+ return getExternalURI(tg, (External)id.definition) + "/" + name;
+ } else if(id.definition instanceof Root) {
+ Root root = (Root)id.definition;
+ return "http:/" + root.name + "/" + name;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public static String getExternalURI(TransferableGraph1 tg, int resource) {
+ Identity id = getIdentity(tg, resource);
+ if(id == null) return null;
+ if(id.definition instanceof External) {
+ External ext = (External)id.definition;
+ return getExternalURI(tg, ext);
+ }
+ return null;
+ }
+
+ String rewritePredicateURI(TransferableGraph1 graph, int predicate) {
+ String uri = getExternalURI(graph, predicate);
+ if(uri == null) return null;
+ uri = uri.replace("http://www.simantics.org/Modeling-1.2", "MOD");
+ uri = uri.replace("http://www.simantics.org/Layer0-1.1", "L0");
+ uri = uri.replace("http://www.simantics.org/Layer0X-1.1", "L0X");
+ uri = uri.replace("http://www.simantics.org/Diagram-2.2", "DIA");
+ uri = uri.replace("http://www.simantics.org/Structural-1.2", "STR");
+ uri = uri.replace("http://www.simantics.org/Documentation-1.2", "DOCU");
+ uri = uri.replace("http://www.simantics.org/Document-1.2", "DOC");
+ uri = uri.replace("http://www.simantics.org/G2D-1.1", "G2D");
+ uri = uri.replace("http://www.simantics.org/Image2-1.2", "IMAGE2");
+ uri = uri.replace("http://www.simantics.org/SelectionView-1.2", "SEL");
+ uri = uri.replace("http://www.simantics.org/GraphFile-0.1", "GRAPHFILE");
+ uri = uri.replace("http://www.semantum.fi/Simupedia-1.0", "SIMUPEDIA");
+ uri = uri.replace("http://www.semantum.fi/SimupediaWorkbench-1.0", "SIMUPEDIA_WB");
+ uri = uri.replace("http://www.apros.fi/OperationUI-6.6", "APROS_OPER");
+ uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk", "SIMUPEDIA_STD");
+ uri = uri.replace("/", ".");
+ return uri;
+ }
+
+ void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info) {
+
+ if(info.hasURI) return;
+ output.append(" " + predicateURI2 + " " + info.name + "\n");
+
+ Value value = findValue(graph, info.resource);
+ if(value != null) {
+
+ }
+
+// for(int i=0;i<info.owned.size();i+=2) {
+// String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
+// ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
+// if(ownedInfo == null) {
+// System.err.println("null owned");
+// continue;
+// }
+// printBlank(graph, predicateURI, ownedInfo);
+// }
+
+ }
+
+ long longStm(int predicate, int object) {
+ return (predicate<<32) | (object & 0xffffffffL);
+ }
+
+ void printURI(TransferableGraph1 graph, ResourceInfo info) {
+ if(!info.hasURI) return;
+ if("ROOT".equals(info.name)) {
+ output.append("ROOT=<http:/>\n");
+ } else {
+ output.append(info.name + "\n");
+ }
+ if(info.newResource)
+ output.append(" @L0.new\n");
+ TLongHashSet processed = new TLongHashSet();
+ for(int i=0;i<info.owned.size();i+=2) {
+ String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
+ ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
+ if(ownedInfo == null) {
+ System.err.println("null owned");
+ continue;
+ }
+ long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
+ processed.add(stmId);
+ printBlank(graph, predicateURI, ownedInfo);
+ }
+ Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ for(int i=0;i<info.statements.size();i+=2) {
+ long stmId = longStm(info.statements.get(i), info.statements.get(i+1));
+ if(processed.contains(stmId)) continue;
+ if(consistsOf.resource == info.statements.get(i)) continue;
+ String predicateURI = rewritePredicateURI(graph, info.statements.get(i));
+ ResourceInfo objectInfo = infos.get(info.statements.get(i+1));
+ if(objectInfo == null) {
+ String objectURI = rewritePredicateURI(graph, info.statements.get(i+1));
+ output.append(" " + predicateURI + " " + objectURI + "\n");
+ } else {
+ output.append(" " + predicateURI + " " + objectInfo.name + "\n");
+ }
+ }
+ }
+
+ void prettyPrint(Path input, Path output) throws Exception {
+ System.out.format("Converting exported shared ontology%n\t" + input.toString() + "%nto bundle-compatible ontology%n\t" + output.toString());
+ try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128*1024)) {
+ DataInput dis = new DataInputStream(is);
+ org.simantics.databoard.container.DataContainer container =
+ DataContainers.readFile(dis);
+ Binding binding = TransferableGraph1.BINDING;
+ TransferableGraph1 graph = (TransferableGraph1)container.content.getValue(binding);
+ // Discover resources with URI
+ for(Identity id : TransferableGraphUtils.getRoots(graph)) {
+ String name = "ROOT";
+ ResourceInfo info = new ResourceInfo(true, name, id.resource);
+ infos.put(id.resource, info);
+ for(Identity child : getChildren(graph, id)) {
+ ResourceInfo childInfo = recurseURI(graph, child, name);
+ childInfo.newResource = true;
+ }
+ }
+ // Discover other resources
+ TIntArrayList todo = new TIntArrayList();
+ for(ResourceInfo info : infos.valueCollection())
+ todo.add(info.resource);
+ while(!todo.isEmpty()) {
+ int resource = todo.removeAt(todo.size()-1);
+ discoverBlank(graph, resource, todo);
+ }
+ for(ResourceInfo info : infos.valueCollection())
+ discoverOwners(graph, info);
+ for(ResourceInfo info : infos.valueCollection())
+ fixInstanceOf(graph, info);
+ for(ResourceInfo info : infos.valueCollection())
+ if(info.owner > 0) {
+ ResourceInfo ownerInfo = infos.get(info.owner);
+ ownerInfo.owned.add(info.ownerPredicate);
+ ownerInfo.owned.add(info.resource);
+ } else if (info.owner == 0) {
+ //System.err.println("faf1");
+ } else if (info.owner == -1) {
+ //System.err.println("faf2");
+ }
+
+ TreeMap<String,ResourceInfo> order = new TreeMap<>();
+ for(ResourceInfo info : infos.valueCollection())
+ order.put(info.name, info);
+
+ this.output.append("MOD = <http://www.simantics.org/Modeling-1.2>\n");
+ this.output.append("L0 = <http://www.simantics.org/Layer0-1.1>\n");
+ this.output.append("L0X = <http://www.simantics.org/Layer0X-1.1>\n");
+ this.output.append("DIA = <http://www.simantics.org/Diagram-2.2>\n");
+ this.output.append("STR = <http://www.simantics.org/Structural-1.2>\n");
+ this.output.append("DOCU = <http://www.simantics.org/Documentation-1.2>\n");
+ this.output.append("DOC = <http://www.simantics.org/Document-1.2>\n");
+ this.output.append("G2D = <http://www.simantics.org/G2D-1.1>\n");
+ this.output.append("SEL = <http://www.simantics.org/SelectionView-1.2>\n");
+ this.output.append("IMAGE2 = <http://www.simantics.org/Image2-1.2>\n");
+ this.output.append("GRAPHFILE = <http://www.simantics.org/GraphFile-0.1>\n");
+ this.output.append("APROS_OPER = <http://www.apros.fi/OperationUI-6.6>\n");
+ this.output.append("SIMUPEDIA = <http://www.semantum.fi/Simupedia-1.0>\n");
+ this.output.append("SIMUPEDIA_WB = <http://www.semantum.fi/SimupediaWorkbench-1.0>\n");
+ this.output.append("SIMUPEDIA_STD = <http://semantum.fi/SimupediaStandardLibrary@1.3-trunk>\n");
+
+// uri = uri.replace("http://semantum.fi/SimupediaStandardLibrary@1.3-trunk/", "SIMUPEDIA_STD.");
+
+
+ for(ResourceInfo info : order.values())
+ printURI(graph, info);
+
+ Files.write(output, this.output.toString().getBytes());
+
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ System.out.println("Required arguments: <input .sharedOntology file> [<output .tg file>]");
+ } else if (args.length < 2) {
+ Path input = Paths.get(args[0]);
+ Path output = input.getParent().resolve(input.getName(input.getNameCount()-1) + ".fixed");
+ new PrettyPrintTG().prettyPrint(input, output);
+ } else {
+ new PrettyPrintTG().prettyPrint(Paths.get(args[0]), Paths.get(args[1]));
+ }
+ }
+
+}
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
public class TransferableGraphUtils {
}
+ public static Identity getIdentity(TransferableGraph1 tg, int resource) {
+ for(Identity id : tg.identities) {
+ if(id.resource == resource) return id;
+ }
+ return null;
+ }
+
+ public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) {
+ TIntArrayList result = new TIntArrayList();
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == resource) {
+ result.add(tg.statements[i+1]);
+ result.add(tg.statements[i+3]);
+ }
+ }
+ return result;
+ }
+
public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
- ArrayList<Identity> result = new ArrayList<Identity>();
- System.err.println("children for " + parent.resource);
+ TreeMap<String,Identity> result = new TreeMap<>();
for(Identity id : tg.identities) {
if(id.definition instanceof Internal) {
Internal internal = (Internal)id.definition;
- System.err.println("internal with parent " + internal.parent);
- if(internal.parent == parent.resource) result.add(id);
+ if(internal.parent == parent.resource) result.put(internal.name, id);
+ }
+ }
+ Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == parent.resource) {
+ if(tg.statements[i+1] == consistsOf.resource) {
+ Identity identity = getIdentity(tg, tg.statements[i+3]);
+ if(identity != null) {
+ if(identity.definition instanceof Internal) {
+ Internal internal = (Internal)identity.definition;
+ result.put(internal.name, identity);
+ }
+ } else {
+ int possibleNameResource = getPossibleObject(tg, tg.statements[i+3], hasName);
+ if(possibleNameResource != 0) {
+ Value value = findValue(tg, possibleNameResource);
+ if(value != null) {
+ try {
+ String name = (String)value.value.getValue(Bindings.STRING);
+ result.put(name, new Identity(tg.statements[i+3], new Internal(tg.statements[i], name)));
+ } catch (AdaptException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
}
}
- findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ return result.values();
+ }
+
+ public static TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
+ TIntArrayList result = new TIntArrayList();
for(int i=0;i<tg.statements.length;i+=4) {
- if(tg.statements[i] == parent.resource)
- System.err.println("related to parent " + tg.statements[i+3]);
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ result.add(tg.statements[i+3]);
+ }
}
return result;
}
- public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
- Identity p = findExternal(tg, predicate);
- if(p == null) return 0;
+ public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
int result = 0;
for(int i=0;i<tg.statements.length;i+=4) {
- if(tg.statements[i] == subject.resource && tg.statements[i+1] == p.resource) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
if(result != 0) return 0;
result = tg.statements[i+3];
}
}
return result;
}
+
+ public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
+ Identity p = findExternal(tg, predicate);
+ if(p == null) return 0;
+ return getPossibleObject(tg, subject.resource, p);
+ }
public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
Map<Identity, String> result = new HashMap<Identity, String>();
else return getURI(resourceCount, identities, def.parent) + "/" + def.name;
} else if(definition instanceof Root) {
Root def = (Root)definition;
+ if(def.name.isEmpty()) return "http:/";
return def.name;
} else if (definition instanceof Internal) {
Internal def = (Internal)definition;
- System.err.println("External URI error: parent was internal '" + def.name + "'");
- return "";
+ return getURI(resourceCount, identities, def.parent) + "/" + def.name;
} else {
return "";
}
}
return "<internal reference " + id + ">:";
}
-
+
+ public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
+ return mapIdentities(tg.identities);
+ }
+
+ public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
+ // Integer.MIN_VALUE cannot be the value of Identity.resource
+ TIntObjectMap<Identity> map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE);
+ for (Identity id : identities)
+ map.put(id.resource, id);
+ return map;
+ }
+
+ public static String getURI(int resourceCount, TIntObjectMap<Identity> identities, int id) {
+ Identity identity = identities.get(id);
+ if(identity != null) {
+ IdentityDefinition definition = identity.definition;
+ if(definition instanceof External) {
+ External def = (External)definition;
+ if(def.parent == -1) return "http:/";
+ else return getURI(resourceCount, identities, def.parent) + "/" + def.name;
+ } else if(definition instanceof Root) {
+ Root def = (Root)definition;
+ if(def.name.isEmpty()) return "http:/";
+ return def.name;
+ } else if (definition instanceof Internal) {
+ Internal def = (Internal)definition;
+ return getURI(resourceCount, identities, def.parent) + "/" + def.name;
+ } else {
+ return "";
+ }
+ }
+ return "<internal reference " + id + ">:";
+ }
+
}
public synchronized static TDoubleArrayList sample( HistorySamplerItem item, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {
try {
- item.open();
+ // If there is something pending at this point, flush before opening for read
if(item.collector != null)
item.collector.flush();
+ item.open();
return sample(item.iter, from, end, timeWindow, timeStep, resample);
} finally {
item.close();
}
public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample ) throws HistoryException, IOException {
+ return sample(iter, from, end, timeWindow, timeStep, resample, 0.0);
+ }
+
+ public static TDoubleArrayList sample( StreamIterator iter, double from, double end, double timeWindow, double timeStep, boolean resample, Double sampleFrom ) throws HistoryException, IOException {
ExportInterpolation numberInterpolation = ExportInterpolation.LINEAR_INTERPOLATION;
- double startTime = 0.0;
+ double startTime = from;
+ if(sampleFrom != null) {
+ // This option can be used do define the offset of sampling. Samples will be sampleFrom + n * timeStep
+ startTime = sampleFrom;
+ }
TDoubleArrayList result = new TDoubleArrayList();
package org.simantics.issues.common;
+import java.util.Collections;
import java.util.List;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.utils.ListUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
}
}
- @SCLValue(type = "ReadGraph -> Resource -> Variable -> [Resource]")
- public static List<Resource> standardIssueContexts(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
- return IssueUtils.getContextsForProperty(graph, property);
+ @SCLValue(type = "ReadGraph -> Resource -> a -> [Resource]")
+ public static List<Resource> standardIssueContexts(ReadGraph graph, Resource converter, Object property) throws DatabaseException {
+ if (property instanceof Variable) {
+ return IssueUtils.getContextsForProperty(graph, (Variable) property);
+ } else if (property instanceof Resource) {
+ Resource issue = (Resource) property;
+ IssueResource ISSUE = IssueResource.getInstance(graph);
+ Resource list = graph.getPossibleObject(issue, ISSUE.Issue_HasContexts);
+ if(list != null)
+ return ListUtils.toList(graph, list);
+ else
+ return Collections.emptyList();
+ }
+ throw new IllegalArgumentException("Unsupported property type: " + property);
}
}
>-- L0.Ontology.global <R L0.HasProperty : L0.FunctionalRelation
L0.HasLabel "Global?"
--> L0.Boolean
-
+ >-- L0.Ontology.download --> L0.String <R L0.HasProperty : L0.FunctionalRelation
+
L0.SharedOntology <T L0.Ontology
>-- L0.SharedOntology.treatAsSystemOntology --> L0.Boolean <R L0.HasProperty : L0.FunctionalRelation
@L0.assert L0.SharedOntology.treatAsSystemOntology false
L0.PGraph <T L0.Entity
>-- L0.PGraph.definition --> L0.String <R L0.HasProperty : L0.TotalFunction
@L0.assert L0.PGraph.definition ""
+
+L0.ExternalEntity <T L0.Entity
\ No newline at end of file
L0.SCLModule <T L0.Entity
>-- L0.SCLModule.definition --> L0.String <R L0.HasProperty : L0.TotalFunction
+ >-- L0.SCLModule.alias --> L0.String <R L0.HasProperty : L0.TotalFunction
@L0.assert L0.SCLModule.definition ""
+ @L0.assert L0.SCLModule.alias ""
L0.entityReplacer ==> "Resource -> Resource -> <WriteGraph> ()" <R L0.HasProperty : L0.FunctionalRelation
L0.HasDescription """Used for defining an SCL function that knows how to copy the contents from one entity instance to another when both instances are known to be of the same type.
public final Resource Entity_published;
public final Resource Entity_published_Inverse;
public final Resource Enumeration;
+ public final Resource ExternalEntity;
public final Resource ExternalValue;
public final Resource False;
public final Resource Final;
public final Resource NamespaceMigrationStep_Prefix_to;
public final Resource NamespaceMigrationStep_Prefix_to_Inverse;
public final Resource Ontology;
+ public final Resource Ontology_download;
+ public final Resource Ontology_download_Inverse;
public final Resource Ontology_global;
public final Resource Ontology_global_Inverse;
public final Resource OrderedSet;
public final Resource SCLMigrationStep;
public final Resource SCLMigrationStep_SCLMigrationStepAction;
public final Resource SCLModule;
+ public final Resource SCLModule_alias;
+ public final Resource SCLModule_alias_Inverse;
public final Resource SCLModule_definition;
public final Resource SCLModule_definition_Inverse;
public final Resource SCLValue;
public static final String Entity_published = "http://www.simantics.org/Layer0-1.1/Entity/published";
public static final String Entity_published_Inverse = "http://www.simantics.org/Layer0-1.1/Entity/published/Inverse";
public static final String Enumeration = "http://www.simantics.org/Layer0-1.1/Enumeration";
+ public static final String ExternalEntity = "http://www.simantics.org/Layer0-1.1/ExternalEntity";
public static final String ExternalValue = "http://www.simantics.org/Layer0-1.1/ExternalValue";
public static final String False = "http://www.simantics.org/Layer0-1.1/False";
public static final String Final = "http://www.simantics.org/Layer0-1.1/Final";
public static final String NamespaceMigrationStep_Prefix_to = "http://www.simantics.org/Layer0-1.1/NamespaceMigrationStep/Prefix/to";
public static final String NamespaceMigrationStep_Prefix_to_Inverse = "http://www.simantics.org/Layer0-1.1/NamespaceMigrationStep/Prefix/to/Inverse";
public static final String Ontology = "http://www.simantics.org/Layer0-1.1/Ontology";
+ public static final String Ontology_download = "http://www.simantics.org/Layer0-1.1/Ontology/download";
+ public static final String Ontology_download_Inverse = "http://www.simantics.org/Layer0-1.1/Ontology/download/Inverse";
public static final String Ontology_global = "http://www.simantics.org/Layer0-1.1/Ontology/global";
public static final String Ontology_global_Inverse = "http://www.simantics.org/Layer0-1.1/Ontology/global/Inverse";
public static final String OrderedSet = "http://www.simantics.org/Layer0-1.1/OrderedSet";
public static final String SCLMigrationStep = "http://www.simantics.org/Layer0-1.1/SCLMigrationStep";
public static final String SCLMigrationStep_SCLMigrationStepAction = "http://www.simantics.org/Layer0-1.1/SCLMigrationStep/SCLMigrationStepAction";
public static final String SCLModule = "http://www.simantics.org/Layer0-1.1/SCLModule";
+ public static final String SCLModule_alias = "http://www.simantics.org/Layer0-1.1/SCLModule/alias";
+ public static final String SCLModule_alias_Inverse = "http://www.simantics.org/Layer0-1.1/SCLModule/alias/Inverse";
public static final String SCLModule_definition = "http://www.simantics.org/Layer0-1.1/SCLModule/definition";
public static final String SCLModule_definition_Inverse = "http://www.simantics.org/Layer0-1.1/SCLModule/definition/Inverse";
public static final String SCLValue = "http://www.simantics.org/Layer0-1.1/SCLValue";
Entity_published = getResourceOrNull(graph, URIs.Entity_published);
Entity_published_Inverse = getResourceOrNull(graph, URIs.Entity_published_Inverse);
Enumeration = getResourceOrNull(graph, URIs.Enumeration);
+ ExternalEntity = getResourceOrNull(graph, URIs.ExternalEntity);
ExternalValue = getResourceOrNull(graph, URIs.ExternalValue);
False = getResourceOrNull(graph, URIs.False);
Final = getResourceOrNull(graph, URIs.Final);
NamespaceMigrationStep_Prefix_to = getResourceOrNull(graph, URIs.NamespaceMigrationStep_Prefix_to);
NamespaceMigrationStep_Prefix_to_Inverse = getResourceOrNull(graph, URIs.NamespaceMigrationStep_Prefix_to_Inverse);
Ontology = getResourceOrNull(graph, URIs.Ontology);
+ Ontology_download = getResourceOrNull(graph, URIs.Ontology_download);
+ Ontology_download_Inverse = getResourceOrNull(graph, URIs.Ontology_download_Inverse);
Ontology_global = getResourceOrNull(graph, URIs.Ontology_global);
Ontology_global_Inverse = getResourceOrNull(graph, URIs.Ontology_global_Inverse);
OrderedSet = getResourceOrNull(graph, URIs.OrderedSet);
SCLMigrationStep = getResourceOrNull(graph, URIs.SCLMigrationStep);
SCLMigrationStep_SCLMigrationStepAction = getResourceOrNull(graph, URIs.SCLMigrationStep_SCLMigrationStepAction);
SCLModule = getResourceOrNull(graph, URIs.SCLModule);
+ SCLModule_alias = getResourceOrNull(graph, URIs.SCLModule_alias);
+ SCLModule_alias_Inverse = getResourceOrNull(graph, URIs.SCLModule_alias_Inverse);
SCLModule_definition = getResourceOrNull(graph, URIs.SCLModule_definition);
SCLModule_definition_Inverse = getResourceOrNull(graph, URIs.SCLModule_definition_Inverse);
SCLValue = getResourceOrNull(graph, URIs.SCLValue);
L0.SCLValue.expression %expression
L0.HasValueType %valueType
+MOD.sclAssertion : L0.Template
+ @template %type %property %expression %valueType
+ %type
+ L0.Asserts _ : L0.Assertion
+ L0.HasPredicate %property
+ L0.HasObject _ : MOD.SCLValue
+ L0.SCLValue.expression %expression
+ L0.HasValueType %valueType
+
MOD.Functions.obtainedString : L0.Function
L0.HasValueType "String"
ACTIONS.RenameDiagramComponents : ACT.Action
ACTIONS.Help : ACT.Action
+ACTIONS.NavigateToSubstructure
+ @MOD.sclAction "navigateToSubstructureAction"
+
ACTIONS.NewProceduralComponentType : ACT.Action
ACTIONS.NewComponentType : ACT.Action
public final Resource ModelingActionContext_Actions_Lock;
public final Resource ModelingActionContext_Actions_MergeFlags;
public final Resource ModelingActionContext_Actions_MigrateComponentType;
+ public final Resource ModelingActionContext_Actions_NavigateToSubstructure;
public final Resource ModelingActionContext_Actions_NewComponentType;
public final Resource ModelingActionContext_Actions_NewConnectionPoint;
public final Resource ModelingActionContext_Actions_NewDocument;
public final Resource editorContribution;
public final Resource scl;
public final Resource sclAction;
+ public final Resource sclAssertion;
public final Resource sclTest;
public final Resource self;
public final Resource self_Inverse;
public static final String ModelingActionContext_Actions_Lock = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/Lock";
public static final String ModelingActionContext_Actions_MergeFlags = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/MergeFlags";
public static final String ModelingActionContext_Actions_MigrateComponentType = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/MigrateComponentType";
+ public static final String ModelingActionContext_Actions_NavigateToSubstructure = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/NavigateToSubstructure";
public static final String ModelingActionContext_Actions_NewComponentType = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/NewComponentType";
public static final String ModelingActionContext_Actions_NewConnectionPoint = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/NewConnectionPoint";
public static final String ModelingActionContext_Actions_NewDocument = "http://www.simantics.org/Modeling-1.2/ModelingActionContext/Actions/NewDocument";
public static final String editorContribution = "http://www.simantics.org/Modeling-1.2/editorContribution";
public static final String scl = "http://www.simantics.org/Modeling-1.2/scl";
public static final String sclAction = "http://www.simantics.org/Modeling-1.2/sclAction";
+ public static final String sclAssertion = "http://www.simantics.org/Modeling-1.2/sclAssertion";
public static final String sclTest = "http://www.simantics.org/Modeling-1.2/sclTest";
public static final String self = "http://www.simantics.org/Modeling-1.2/self";
public static final String self_Inverse = "http://www.simantics.org/Modeling-1.2/self/Inverse";
ModelingActionContext_Actions_Lock = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_Lock);
ModelingActionContext_Actions_MergeFlags = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_MergeFlags);
ModelingActionContext_Actions_MigrateComponentType = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_MigrateComponentType);
+ ModelingActionContext_Actions_NavigateToSubstructure = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NavigateToSubstructure);
ModelingActionContext_Actions_NewComponentType = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewComponentType);
ModelingActionContext_Actions_NewConnectionPoint = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewConnectionPoint);
ModelingActionContext_Actions_NewDocument = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewDocument);
editorContribution = getResourceOrNull(graph, URIs.editorContribution);
scl = getResourceOrNull(graph, URIs.scl);
sclAction = getResourceOrNull(graph, URIs.sclAction);
+ sclAssertion = getResourceOrNull(graph, URIs.sclAssertion);
sclTest = getResourceOrNull(graph, URIs.sclTest);
self = getResourceOrNull(graph, URIs.self);
self_Inverse = getResourceOrNull(graph, URIs.self_Inverse);
setMonitorPropertyValue :: Monitor -> String -> String -> <WriteGraph> ()
setMonitorPropertyValue monitor property newValue = do
- monitorUri = uriOf (toResource monitor)
+ monitorUri = uriOf monitor
completeUri = monitorUri + "#" + property + "#HasDisplayValue"
propertyVariable = variable completeUri
setValue propertyVariable newValue
setFlagTablePropertyValue :: FlagTable -> String -> String -> <WriteGraph> ()
setFlagTablePropertyValue flagTable property newValue = do
- flagTableUri = uriOf (toResource flagTable)
+ flagTableUri = uriOf flagTable
completeUri = flagTableUri + "#" + property + "#HasDisplayValue"
propertyVariable = variable completeUri
setValue propertyVariable newValue
org.simantics.modeling;bundle-version="1.0.0";visibility:=reexport,
org.simantics.utils.thread.swt;bundle-version="1.0.0",
org.simantics.simulation;bundle-version="1.0.0",
- javax.vecmath;bundle-version="1.5.2",
+ org.apache.commons.math3;bundle-version="3.6.1",
org.simantics.browsing.ui.platform;bundle-version="1.0.0";visibility:=reexport,
org.simantics.structural.ui;bundle-version="1.0.0",
org.eclipse.ui.forms;bundle-version="3.4.1",
org.simantics.silk.ontology;bundle-version="1.1.0",
org.simantics.image.ui;bundle-version="1.0.0",
org.simantics.export.core;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.graphfile.ontology
Export-Package: org.simantics.modeling.ui,
org.simantics.modeling.ui.actions,
org.simantics.modeling.ui.chart.property,
getLibrary :: Model -> String -> <ReadGraph> Library
librariesOf :: Model -> <ReadGraph> [Library]
-librariesOf model = recurse L0.Library (toResource model)
+librariesOf model = recurse L0.Library model
where
recurse t r = do
- cs = resourceChildrenOf r
- libraries = map fromResource $ filter isLibrary cs
+ cs = children r
+ libraries = filter isLibrary cs
libraryGrp = filter (not . isLibrary) cs
libraries + concatMap (recurse t) libraryGrp
isLibrary r = isInstanceOf r L0.Library
\ No newline at end of file
@private
decorateLabelStub :: LabelDecorator -> String -> String -> <Proc> ()
decorateLabelStub decorator key value = do
- fontti = decorateFont decorator getDefaultFontDescriptor key 0
+ fontti = match decorateFont decorator (Just getDefaultFontDescriptor) key 0 with
+ Nothing -> ""
+ Just font -> ""
fontti = decorateBackground decorator Nothing key 0
fontti = decorateForeground decorator Nothing key 0
laabeli = decorateLabel decorator value key 0
decorateLabel :: LabelDecorator -> String -> String -> Integer -> <Proc> String
decorateForeground :: LabelDecorator -> a -> String -> Integer -> <Proc> a
decorateBackground :: LabelDecorator -> a -> String -> Integer -> <Proc> a
- decorateFont :: LabelDecorator -> a -> String -> Integer -> <Proc> a
+ decorateFont :: LabelDecorator -> Maybe a -> String -> Integer -> <Proc> Maybe a
importJava "org.simantics.browsing.ui.CheckedState" where
data CheckedState
data Modifier
getValue :: Modifier -> <Proc> String
- isValid :: Modifier -> String -> <Proc> String
+ isValid :: Modifier -> String -> <Proc> Maybe String
+ modify :: Modifier -> String -> <Proc> ()
importJava "org.simantics.browsing.ui.model.browsecontexts.BrowseContexts" where
toBrowseContextG :: Vector String -> <ReadGraph> BrowseContext
createBrowseContext resource = do
create resource
+importJava "org.simantics.browsing.ui.common.NodeContextBuilder" where
+ buildWithInput :: a -> <Proc> NodeContext
+
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.IndexRoot;
import org.simantics.db.common.request.ObjectsWithType;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
import org.simantics.db.service.SerialisationSupport;
import org.simantics.graph.compiler.CompilationResult;
+import org.simantics.graph.compiler.ExternalFileLoader;
import org.simantics.graph.compiler.GraphCompiler;
import org.simantics.graph.compiler.GraphCompilerPreferences;
import org.simantics.graph.compiler.ValidationMode;
import org.simantics.graph.representation.Identity;
import org.simantics.graph.representation.Root;
import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.graphfile.ontology.GraphFileResource;
import org.simantics.layer0.Layer0;
import org.simantics.ltk.ISource;
import org.simantics.ltk.Problem;
prefs.validate = true;
prefs.validateRelationRestrictions = ValidationMode.ERROR;
prefs.validateResourceHasType = ValidationMode.IGNORE;
- final CompilationResult result = GraphCompiler.compile("1.1", sources, dependencies, null, prefs);
+
+ final CompilationResult result = Simantics.sync(new UniqueRead<CompilationResult>() {
+
+ @Override
+ public CompilationResult perform(ReadGraph graph) throws DatabaseException {
+
+ final Resource root = graph.syncRequest(new IndexRoot(r));
+ final String baseURI = graph.getURI(root);
+
+ ExternalFileLoader fileLoader = new ExternalFileLoader() {
+ @Override
+ public byte[] load(String fileName) throws IOException {
+ try {
+ GraphFileResource GF = GraphFileResource.getInstance(graph);
+ Resource file = graph.getResource(baseURI + "/" + fileName);
+ return graph.getRelatedValue(file, GF.HasFiledata, Bindings.BYTE_ARRAY);
+ } catch (DatabaseException e) {
+ throw new IOException(e);
+ }
+ }
+ };
+
+ return GraphCompiler.compile("1.1", sources, dependencies, fileLoader, prefs);
+
+ }
+
+ });
for(Problem problem : result.getErrors())
errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n");
for (Object o : selection) {
if ((o instanceof IAdaptable)) {
NodeContext nodeContext = ((IAdaptable) o).getAdapter(NodeContext.class);
- if (nodeContext != null)
+ if (nodeContext != null) {
result.add(nodeContext);
- } else if (o instanceof WorkbenchSelectionElement) {
- try {
- Resource res = WorkbenchSelectionUtils.getPossibleResource((WorkbenchSelectionElement)o);
- if(res != null) {
- result.add(NodeContextBuilder.buildWithInput(res));
- }
- } catch (DatabaseException e) {
- LOGGER.error("Failed to get node contexts for selection.", e);
- }
+ continue;
+ }
+ }
+ try {
+ Resource res = WorkbenchSelectionUtils.getPossibleResource(o);
+ if(res != null) {
+ result.add(NodeContextBuilder.buildWithInput(res));
+ }
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to get node contexts for selection.", e);
}
}
errorHappened = false;
return graph.getRelatedValue(text, L0.SCLValue_expression, Bindings.STRING);
}
- throw new DatabaseException("No symbol code was defined.");
+ return "";
}
protected void updateAnnotations() {
errorHappened = false;
return graph.getRelatedValue(text, L0.SCLValue_expression, Bindings.STRING);
}
- throw new DatabaseException("No symbol code was defined.");
+ return "";
}
protected void updateAnnotations() {
import java.util.EnumSet;
import javax.swing.JSlider;
-import javax.vecmath.Vector2d;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.simantics.g2d.diagram.IDiagram;
import org.simantics.g2d.element.ElementClass;
import org.simantics.g2d.element.ElementHints;
return Double.NaN;
double angrad = Math.toRadians(angle);
- Vector2d forcedAxis = new Vector2d(Math.cos(angrad), Math.sin(angrad));
- Vector2d x = new Vector2d(tr.getScaleX(), tr.getShearX());
- forcedAxis.normalize();
- x.normalize();
- double cosa = forcedAxis.dot(x);
+ Vector2D forcedAxis = new Vector2D(Math.cos(angrad), Math.sin(angrad));
+ Vector2D x = new Vector2D(tr.getScaleX(), tr.getShearX()).normalize();
+ double cosa = forcedAxis.dotProduct(x);
double delta = Math.acos(cosa);
return delta;
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - #7107 original implementation
+ * Semantum Oy - #7107 adaptation for general use
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagram.style;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.primitiverequest.OrderedSet;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.diagram.adapter.RouteGraphUtils;
+import org.simantics.diagram.connection.RouteGraphConnectionClass;
+import org.simantics.diagram.connection.RouteTerminal;
+import org.simantics.diagram.elements.TextNode;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.diagram.synchronization.graph.BasicResources;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.g2d.utils.Alignment;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.utils.datastructures.map.Tuple;
+
+/**
+ * @author Teemu Mätäsniemi
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class ConnectionPointNameStyle extends StyleBase<List<ConnectionPointNameStyle.Result>> {
+
+ protected static class Result extends Tuple {
+ public Result(String string, AffineTransform tr, Integer direction) {
+ super(string, tr, direction);
+ }
+ public String getString() {
+ return (String) getField(0);
+ }
+ public AffineTransform getTransform() {
+ return (AffineTransform) getField(1);
+ }
+ public Integer getAllowedDirections() {
+ return (Integer) getField(2);
+ }
+ }
+
+ protected static final String PARENT_NODE_NAME_PREFIX = "_tNames";
+ protected static final String NODE_NAME_PREFIX = "_";
+
+ protected static final Font FONT = Font.decode("Arial 6");
+
+ protected static final double DEFAULT_SCALE = 0.05;
+
+ private Color backgroundColor = Color.WHITE;
+ private Color textColor = Color.BLACK;
+
+ private double textScale;
+
+ public ConnectionPointNameStyle() {
+ this(DEFAULT_SCALE);
+ }
+
+ public ConnectionPointNameStyle(double textScale) {
+ this.textScale = textScale;
+ }
+
+ @Override
+ public List<Result> calculateStyle(
+ ReadGraph graph,
+ Resource runtimeDiagram,
+ Resource entry,
+ Resource element,
+ Variable configuration)
+ throws DatabaseException
+ {
+ BasicResources BR = BasicResources.getInstance(graph);
+ Layer0 L0 = BR.L0;
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+
+ Resource comp = graph.getPossibleObject(element, MOD.ElementToComponent);
+ if (comp == null)
+ return Collections.emptyList();
+ String compName = graph.getPossibleRelatedValue(comp, L0.HasName, Bindings.STRING);
+ if (compName == null)
+ return Collections.emptyList();
+
+ // Only process defined elements since those can contain terminal definitions
+ Resource elementType = graph.getPossibleType(element, BR.DIA.DefinedElement);
+ if (elementType == null)
+ return Collections.emptyList();
+
+ // Need parent information to calculate absolute positions of terminals
+ // and to make the result unique for instances of the same symbol.
+ AffineTransform parentTransform = DiagramGraphUtil.getAffineTransform(graph, element);
+ List<Result> result = new ArrayList<>();
+ result.add(new Result(compName, parentTransform, null));
+
+ Resource orderedSet = graph.getPossibleObject(elementType, BR.STR.IsDefinedBy);
+ if (orderedSet != null) {
+ for (Resource el : graph.syncRequest(new OrderedSet(orderedSet))) {
+ Resource gcp = graph.getPossibleObject(el, BR.DIA.HasConnectionPoint);
+ if (gcp != null) {
+ Resource cpRel = graph.getPossibleObject(gcp, MOD.DiagramConnectionRelationToConnectionRelation);
+ if (cpRel == null)
+ continue;
+ String name = graph.getPossibleRelatedValue(cpRel, L0.HasName, Bindings.STRING);
+ if (name != null) {
+ Integer allowedDirections = graph.getPossibleRelatedValue(el, BR.DIA.Terminal_AllowedDirections, Bindings.INTEGER);
+ result.add(new Result(name, DiagramGraphUtil.getAffineTransform(graph, el), allowedDirections));
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected static AffineTransform translateAndScaleIfNeeded(AffineTransform tr, double rotation, double offsetX, double offsetY, double scale) {
+ if (rotation != 0 || offsetX != 0.0 || offsetY != 0.0 || scale != 1.0) {
+ tr = new AffineTransform(tr);
+ if (rotation != 0)
+ tr.rotate(rotation);
+ if (offsetX != 0 || offsetY != 0)
+ tr.translate(offsetX, offsetY);
+ if (scale != 1.0)
+ tr.scale(scale, scale);
+ }
+ return tr;
+ }
+
+ protected AffineTransform getTerminalTransform(AffineTransform transform, double rotation, double offsetX, double offsetY, double scale) {
+ return translateAndScaleIfNeeded(transform, rotation, offsetX, offsetY, scale);
+ }
+
+ @Override
+ public void applyStyleForNode(EvaluationContext observer, INode _node, List<Result> resultList) {
+ // always clean up old items before drawing new items
+ cleanupStyleForNode(_node);
+
+ int count = resultList.size();
+ if (resultList == null || count < 2)
+ return;
+
+ G2DParentNode parentNode = ProfileVariables.claimChild(_node, "", PARENT_NODE_NAME_PREFIX, G2DParentNode.class, observer);
+ parentNode.setTransform(resultList.get(0).getTransform());
+ parentNode.setZIndex(Integer.MAX_VALUE >> 1);
+
+ Rectangle2D eBounds = NodeUtil.getLocalElementBounds(_node);
+
+ for (int i = 1; i < count; ++i) {
+ Result result = resultList.get(i);
+ TextNode node = ProfileVariables.claimChild(parentNode, "", NODE_NAME_PREFIX + i, TextNode.class, observer);
+ node.setZIndex(i);
+ node.setBackgroundColor(backgroundColor);
+ node.setColor(textColor);
+ node.setText(result.getString());
+ node.setVerticalAlignment((byte) Alignment.CENTER.ordinal());
+ node.setAutomaticTextFlipping(TextNode.TextFlipping.VerticalTextDownwards);
+
+ Alignment hAlign = Alignment.LEADING;
+ AffineTransform tr = result.getTransform();
+ double trX = tr.getTranslateX(),
+ trY = tr.getTranslateY();
+ double dx = 0, dy = 0, r = 0;
+ double ts = 0.6;
+
+ Integer dir = result.getAllowedDirections();
+ int directions = dir != null
+ ? RouteGraphUtils.rotateDirection(dir, tr)
+ : RouteGraphConnectionClass.shortestDirectionOutOfBounds(trX, trY, eBounds);
+
+ //System.out.format("%24s: DIR %d (%s)%n", result.getString(), directions, tr.toString());
+
+ if (trX == 0 && trY == 0) {
+ hAlign = Alignment.CENTER;
+ } else {
+ boolean up = (directions & RouteTerminal.DIR_UP) != 0;
+ boolean down = (directions & RouteTerminal.DIR_DOWN) != 0;
+ boolean left = (directions & RouteTerminal.DIR_LEFT) != 0;
+ boolean right = (directions & RouteTerminal.DIR_RIGHT) != 0;
+
+ double ldx = Math.abs(eBounds.getMinX() - trX);
+ double rdx = Math.abs(eBounds.getMaxX() - trX);
+ double tdy = Math.abs(eBounds.getMinY() - trY);
+ double bdy = Math.abs(eBounds.getMaxY() - trY);
+
+ if (left && ldx <= rdx && ldx <= tdy && ldx <= bdy) {
+ dx = -ts;
+ hAlign = Alignment.TRAILING;
+ } else if (right && rdx <= ldx && rdx <= tdy && rdx <= bdy) {
+ dx = ts;
+ hAlign = Alignment.LEADING;
+ } else if (up && tdy <= ldx && tdy <= rdx && tdy <= bdy) {
+ dx = -ts;
+ r = Math.PI/2;
+ hAlign = Alignment.TRAILING;
+ } else if (down && bdy <= ldx && bdy <= rdx && bdy <= tdy) {
+ dx = ts;
+ r = Math.PI/2;
+ hAlign = Alignment.LEADING;
+ }
+ }
+
+ node.setHorizontalAlignment((byte) hAlign.ordinal());
+ node.setTransform(getTerminalTransform(tr, r, dx, dy, textScale));
+ }
+ }
+
+ @Override
+ protected void cleanupStyleForNode(INode node) {
+ if (node instanceof SingleElementNode) {
+ ProfileVariables.denyChild(node, "", PARENT_NODE_NAME_PREFIX);
+ }
+ }
+
+}
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - #7116 regression fix
*******************************************************************************/
package org.simantics.modeling.ui.modelBrowser.handlers;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
-import org.simantics.db.common.request.ResourceRead;
-import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.modeling.ModelingResources;
import org.simantics.modeling.PropertyVariables;
import org.simantics.ui.selection.WorkbenchSelectionUtils;
import org.simantics.utils.ui.AdaptionUtils;
+import org.slf4j.LoggerFactory;
public class ContextualHelp extends AbstractHandler {
+ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ContextualHelp.class);
+
private static String getPossibleId(ExecutionEvent event) {
- String id = null;
try {
- Resource element = WorkbenchSelectionUtils.getPossibleResource(event);
- id = Simantics.getSession().syncRequest(new ResourceRead<String>(element) {
+ ISelection sel = HandlerUtil.getCurrentSelection(event);
+ Resource resource = WorkbenchSelectionUtils.getPossibleResource(sel);
+ Variable variable = WorkbenchSelectionUtils.getPossibleVariable(sel);
+ if (sel.isEmpty() && resource == null && variable == null)
+ return null;
+ return Simantics.getSession().syncRequest(new UniqueRead<String>() {
@Override
public String perform(ReadGraph graph) throws DatabaseException {
ModelingResources MOD = ModelingResources.getInstance(graph);
- Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
- if (component != null)
- return graph.getPossibleRelatedValue2(component, MOD.contextualHelpId, Bindings.STRING);
+ if (resource != null) {
+ Resource component = graph.getPossibleObject(resource, MOD.ElementToComponent);
+ String id = component != null ? graph.getPossibleRelatedValue2(component, MOD.contextualHelpId, Bindings.STRING) : null;
+ if (id != null)
+ return id;
+ id = graph.getPossibleRelatedValue2(resource, MOD.contextualHelpId, Bindings.STRING);
+ if (id != null)
+ return id;
+ }
- Variable var = WorkbenchSelectionUtils.getPossibleVariable(event);
- if (var != null)
- return var.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING);
+ if (variable != null) {
+ String id = variable.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING);
+ if (id != null)
+ return id;
+ }
- ISelection sel = HandlerUtil.getCurrentSelection(event);
+ // TODO: consider removing this block
if (sel != null) {
PropertyVariables vars = AdaptionUtils.adaptToSingle(sel, PropertyVariables.class);
- if (vars != null) {
- var = vars.getConfiguration();
- if (var != null)
- var.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING);
- }
+ Variable var = vars != null ? vars.getConfiguration() : null;
+ String id = var != null ? var.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING) : null;
+ if (id != null)
+ return id;
}
+
return null;
}
});
} catch (DatabaseException e) {
- Logger.defaultLogError(e);
+ LOGGER.error("", e);
+ return null;
}
- return id;
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
-
String id = getPossibleId(event);
if (id != null)
PlatformUI.getWorkbench().getHelpSystem().displayHelp(id);
-
return null;
-
}
}
static LabelDecorator DECO = new LabelDecorator.Stub() {
@SuppressWarnings("unchecked")
public <F> F decorateFont(F font, String column, int itemIndex) {
- return (F) ((FontDescriptor) font).withStyle(SWT.BOLD);
+ return font != null ? (F) ((FontDescriptor) font).withStyle(SWT.BOLD) : null;
}
};
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - (#7084) refactoring, page numbering support
*******************************************************************************/
package org.simantics.modeling.ui.pdf;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.Security;
import java.util.Collection;
-import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IProgressMonitor;
import org.simantics.db.Session;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.util.SessionGarbageCollection;
-import org.simantics.db.management.ISessionContext;
import org.simantics.document.DocumentSettings;
import org.simantics.document.DocumentUtils;
+import org.simantics.export.core.pdf.FontMapping;
+import org.simantics.export.core.pdf.PageNumbering;
import org.simantics.export.core.pdf.ServiceBasedPdfExportPageEvent;
import org.simantics.modeling.requests.CollectionRequest;
import org.simantics.modeling.requests.CollectionResult;
import org.simantics.utils.page.PageDesc;
import org.simantics.utils.page.PageOrientation;
import org.simantics.utils.threads.WorkerThread;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.kitfox.svg.SVGCache;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
-import com.lowagie.text.FontFactory;
+import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.DefaultFontMapper;
+import com.lowagie.text.pdf.FontMapper;
import com.lowagie.text.pdf.PdfBoolean;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfTemplate;
import com.lowagie.text.pdf.PdfWriter;
+/**
+ * @author Tuukka Lehtonen
+ */
public class DiagramPrinter {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DiagramPrinter.class);
+
public static CollectionResult browse(IProgressMonitor monitor, RequestProcessor processor, Resource[] input) throws DatabaseException {
final CollectionResult result = processor.syncRequest(new CollectionRequest(monitor, DiagramPreferenceUtil.getDefaultPreferences().getCompletePageDesc(), input));
return result;
}
- private static final AtomicBoolean fontFactoryInitialized = new AtomicBoolean();
-
/**
* @param monitor the progress monitor to use for reporting progress to the
* user. It is the caller's responsibility to call done() on the
* @throws FileNotFoundException
*/
public static void printToPdf(
- IProgressMonitor monitor,
- PDFExportPlan exportPlan,
- String exportPath,
- Collection<Node> flattenedNodes,
- ISessionContext sessionContext)
- throws PdfException {
- Collection<Node> flattened = flattenedNodes;
+ IProgressMonitor monitor,
+ PDFExportPlan exportPlan,
+ String exportPath,
+ Collection<Node> flattenedNodes)
+ throws PdfException
+ {
+ if (!exportPlan.addPageNumbers) {
+ printToPdfWithoutPageNumbers(monitor, exportPlan, exportPath, flattenedNodes);
+ } else {
+ SubMonitor mon = SubMonitor.convert(monitor, "Export to PDF", flattenedNodes.size() * 3);
+
+ Path tempOutput = Paths.get(exportPath + ".tmp");
+ Path finalOutput = Paths.get(exportPath);
+
+ int exportedPages = printToPdfWithoutPageNumbers(
+ mon.newChild(flattenedNodes.size() * 2, SubMonitor.SUPPRESS_NONE),
+ exportPlan,
+ tempOutput.toString(),
+ flattenedNodes);
+
+ if (mon.isCanceled()) {
+ tempOutput.toFile().delete();
+ throw new OperationCanceledException();
+ }
- SubMonitor progress = SubMonitor.convert(monitor, "Export to PDF", flattened.size() * 2);
+ try {
+ mon.setWorkRemaining(exportedPages);
+ mon.setTaskName("Numbering output pages");
+ mon.subTask("");
+ PageNumbering.addPageNumbers(
+ mon.newChild(flattenedNodes.size()),
+ tempOutput, finalOutput,
+ exportPlan.pageNumberPosition,
+ exportPlan.pageNumberFormat);
+ } catch (IOException | DocumentException | ExceptionConverter e) {
+ throw new PdfException(e);
+ } finally {
+ tempOutput.toFile().delete();
+ }
+ }
+ }
+
+ /**
+ * @param monitor the progress monitor to use for reporting progress to the
+ * user. It is the caller's responsibility to call done() on the
+ * given monitor. Accepts <code>null</code>, indicating that no
+ * progress should be reported and that the operation cannot be
+ * cancelled.
+ *
+ * @param exportPath
+ * @param flattenedNodes
+ * @return number of pages printed
+ * @throws PdfException
+ * @since 1.28.0
+ */
+ public static int printToPdfWithoutPageNumbers(
+ IProgressMonitor monitor,
+ PDFExportPlan exportPlan,
+ String exportPath,
+ Collection<Node> flattenedNodes)
+ throws PdfException
+ {
+ SubMonitor progress = SubMonitor.convert(monitor, "Export to PDF", flattenedNodes.size() * 2);
WorkerThread workerThread = new WorkerThread("Diagram PDF Painter");
workerThread.start();
PdfWriter writer = null;
Document document = null;
+ int exportedPages = 0;
try {
progress.subTask("Loading system fonts");
- DefaultFontMapper mapper = new DefaultFontMapper();
- if (fontFactoryInitialized.compareAndSet(false, true)) {
- // Only register directories once.
- FontFactory.registerDirectories();
- }
+ FontMapper mapper = FontMapping.defaultFontMapper();
SessionGarbageCollectorJob.getInstance().setEnabled(false);
-
- boolean first = true;
+ boolean first = true;
int i = 0;
- for (Node d : flattened) {
+ for (Node d : flattenedNodes) {
++i;
-
+
//System.out.println("PAGE DESC: " + d.getPageDesc());
//System.out.println("PAGE SIZE: " + pageSize);
if (writer == null) {
document = new Document(pageSize);
writer = PdfWriter.getInstance(document, new FileOutputStream(exportPath));
- writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
- writer.setPageEvent(new ServiceBasedPdfExportPageEvent());
- if ( exportPlan.attachTG ) {
- writer.addViewerPreference(PdfName.USEATTACHMENTS, PdfBoolean.PDFTRUE);
- }
+ writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
+ writer.setPageEvent(new ServiceBasedPdfExportPageEvent());
+ if ( exportPlan.attachTG ) {
+ writer.addViewerPreference(PdfName.USEATTACHMENTS, PdfBoolean.PDFTRUE);
+ }
- String creator = getCreator();
- document.addCreator(creator);
-
- /*
- File keystoreFile = new File("c:\\0009278.p12");
- String password = "ka7GfzI9Oq";
-
- try {
- KeyStore ks = KeyStore.getInstance("pkcs12");
- ks.load(new FileInputStream(keystoreFile), password.toCharArray());
- List<String> aliases = Collections.list(ks.aliases());
- String alias = aliases.get(0);
- PrivateKey key = (PrivateKey)ks.getKey(alias, password.toCharArray());
- Certificate[] chain = ks.getCertificateChain(alias);
- int permission = PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY;
-
- PdfEncryption crypto = new PdfEncryption();
- //for (Certificate c : chain) crypto.addRecipient(c, permission);
- //crypto.addRecipient(chain[2], permission);
- crypto.setCryptoMode(PdfWriter.ENCRYPTION_AES_128, 0);
- crypto.setupByEncryptionKey(key.getEncoded(), key.getEncoded().length*8);
- crypto.getEncryptionDictionary();
-
-
- } catch (Exception e) {
- e.printStackTrace();
- }*/
-
- /*
- writer.setEncryption(
- new Certificate[] {},
- new int[] {PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING},
- PdfWriter.STANDARD_ENCRYPTION_128);
- */
- //writer.setEncryption(PdfWriter.STANDARD_ENCRYPTION_128, "", "password", PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY);
-
-
-// PdfName companyName = new PdfName("SMTC");
-// PdfDeveloperExtension ext = new PdfDeveloperExtension(companyName, PdfWriter.PDF_VERSION_1_7, 3);
-// writer.addDeveloperExtension( ext );
-
+ String creator = getCreator();
+ document.addCreator(creator);
+
+ /*
+ File keystoreFile = new File("c:\\0009278.p12");
+ String password = "ka7GfzI9Oq";
+
+ try {
+ KeyStore ks = KeyStore.getInstance("pkcs12");
+ ks.load(new FileInputStream(keystoreFile), password.toCharArray());
+ List<String> aliases = Collections.list(ks.aliases());
+ String alias = aliases.get(0);
+ PrivateKey key = (PrivateKey)ks.getKey(alias, password.toCharArray());
+ Certificate[] chain = ks.getCertificateChain(alias);
+ int permission = PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY;
+
+ PdfEncryption crypto = new PdfEncryption();
+ //for (Certificate c : chain) crypto.addRecipient(c, permission);
+ //crypto.addRecipient(chain[2], permission);
+ crypto.setCryptoMode(PdfWriter.ENCRYPTION_AES_128, 0);
+ crypto.setupByEncryptionKey(key.getEncoded(), key.getEncoded().length*8);
+ crypto.getEncryptionDictionary();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }*/
+
+ /*
+ writer.setEncryption(
+ new Certificate[] {},
+ new int[] {PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING},
+ PdfWriter.STANDARD_ENCRYPTION_128);
+ */
+ //writer.setEncryption(PdfWriter.STANDARD_ENCRYPTION_128, "", "password", PdfWriter.ALLOW_FILL_IN|PdfWriter.ALLOW_PRINTING|PdfWriter.ALLOW_COPY|PdfWriter.ALLOW_ASSEMBLY);
+
+// PdfName companyName = new PdfName("SMTC");
+// PdfDeveloperExtension ext = new PdfDeveloperExtension(companyName, PdfWriter.PDF_VERSION_1_7, 3);
+// writer.addDeveloperExtension( ext );
+
document.open();
}
if (!first) {
- document.setPageSize(pageSize);
- document.newPage();
+ document.setPageSize(pageSize);
+ document.newPage();
}
/*
/// ATTACHMENTS - TG ///
byte[] attachment = null;
- if ( exportPlan.attachTG && !d.getDefiningResources().isEmpty() )
+ if ( exportPlan.attachTG && !d.getDefiningResources().isEmpty() )
try {
PdfDictionary fileParameter = new PdfDictionary();
- {
- final Resource composite = d.getDefiningResources().iterator().next();
- final Session session = exportPlan.sessionContext.getSession();
-
- SimanticsClipboard clipboard = session.syncRequest(new Read<SimanticsClipboard>() {
- @Override
- public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException {
- CopyHandler ch = graph.adapt(composite, CopyHandler.class);
- SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
- ch.copyToClipboard(graph, clipboard);
- return clipboard;
- }
- });
- for (Set<Representation> object : clipboard.getContents()) {
- TransferableGraph1 tg = ClipboardUtils.accept(object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
- String filename = d.getName()+".diagram";
- try {
- byte[] data = DataContainers.writeFile(
- new DataContainer("aprosDiagram", 1, new Variant(TransferableGraph1.BINDING, tg))
- );
- PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
- writer,
- "/Diagram", filename, data, true, "application/simantics/diagram",
- fileParameter);
- writer.addFileAttachment(d.getName()+".diagram", fs);
- } catch ( NullPointerException npe ) {
- throw new PdfException("Experiment must be activated to export attachments"+npe.getMessage(), npe);
- }
- }
- }
+ {
+ final Resource composite = d.getDefiningResources().iterator().next();
+ final Session session = exportPlan.sessionContext.getSession();
+
+ SimanticsClipboard clipboard = session.syncRequest(new Read<SimanticsClipboard>() {
+ @Override
+ public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException {
+ CopyHandler ch = graph.adapt(composite, CopyHandler.class);
+ SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
+ ch.copyToClipboard(graph, clipboard);
+ return clipboard;
+ }
+ });
+ for (Set<Representation> object : clipboard.getContents()) {
+ TransferableGraph1 tg = ClipboardUtils.accept(object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
+ String filename = d.getName()+".diagram";
+ try {
+ byte[] data = DataContainers.writeFile(
+ new DataContainer("aprosDiagram", 1, new Variant(TransferableGraph1.BINDING, tg))
+ );
+ PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(
+ writer,
+ "/Diagram", filename, data, true, "application/simantics/diagram",
+ fileParameter);
+ writer.addFileAttachment(d.getName()+".diagram", fs);
+ } catch ( NullPointerException npe ) {
+ throw new PdfException("Experiment must be activated to export attachments"+npe.getMessage(), npe);
+ }
+ }
+ }
} catch (DatabaseException e) {
e.printStackTrace();
}
*/
//////////////////////////
-
+
String diagramName = formDiagramName(d, true);
- String subTask = "Page (" + i + "/" + flattened.size() + "): " + diagramName;
+ String subTask = "Page (" + i + "/" + flattenedNodes.size() + "): " + diagramName;
Resource diagram = d.getDiagramResource();
if (diagram == null) {
// No diagram, skip page.
subTask += " skipped, no diagram.";
- System.out.println(subTask);
+ LOGGER.info(subTask);
continue;
}
- System.out.println(subTask);
+ LOGGER.info(subTask);
progress.subTask(subTask);
try {
- PDFPainter.render(workerThread, sessionContext, exportPlan, d, writer, mapper,
+ PDFPainter.render(workerThread, exportPlan, d, writer, mapper,
pageSize, d.getPageDesc(), exportPlan.fitContentToPageMargins, 10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (DatabaseException e) {
- e.printStackTrace();
+ ++exportedPages;
+ } catch (DatabaseException | InterruptedException e) {
+ LOGGER.error("PDF rendering failed.", e);
}
- // Paint diagram path/name on the page
- // TODO: remove this hard coded diagram name printing and
- // replace it with a page templates that is loaded along with
- // the rest of the diagram
-
- int w = (int) pageSize.getWidth();
- int h = (int) pageSize.getHeight();
-
- // Write Page Number
- PdfContentByte cb = writer.getDirectContent();
-
-// PdfTemplate tp = cb.createTemplate(w, h);
-// Graphics2D g2d = tp.createGraphics(w, h, mapper);
-// g2d.setColor(Color.black);
-// java.awt.Font thisFont = new java.awt.Font("Arial", java.awt.Font.ITALIC, 10);
-// g2d.setFont(thisFont);
-// FontMetrics metrics = g2d.getFontMetrics();
-// int width = metrics.stringWidth(diagramName);
-// g2d.drawString(diagramName, (w - width) / 2, document.getPageSize().getHeight() - PageDesc.toPoints(5));
-// g2d.dispose();
-// cb.addTemplate(tp, 0, 0);
-
/// ATTACHMENTS - Write WIKI ///
if ( exportPlan.attachWiki && !d.getDefiningResources().isEmpty() ) {
- final Session session = exportPlan.sessionContext.getSession();
+ int w = (int) pageSize.getWidth();
+ int h = (int) pageSize.getHeight();
+ PdfContentByte cb = writer.getDirectContent();
+ Session session = exportPlan.sessionContext.getSession();
Resource composite = d.getDefiningResources().iterator().next();
DocumentUtils du = new DocumentUtils();
StringBuilder wiki = new StringBuilder();
StringBuilder css = new StringBuilder();
du.getDocumentWikiTextRecursive(session, composite, wiki, css);
- DocumentSettings settings = du.getDocumentSettings(session, composite);
+ DocumentSettings settings = du.getDocumentSettings(session, composite);
PdfTemplate tp_ = cb.createTemplate(w, h);
if ( wiki.length()>0 ) {
String wikiText = wiki.toString();
String cssText = css.toString();
- du.print(session, composite, wikiText, cssText, settings, tp_.getPdfWriter(), document);
+ try {
+ exportedPages += du.print(session, composite, wikiText, cssText, settings, tp_.getPdfWriter(), document);
+ } catch (DatabaseException | DocumentException e) {
+ LOGGER.error("Wiki documentation to PDF rendering failed.", e);
+ }
}
cb.addTemplate(tp_, 0, 0);
}
if (progress.isCanceled())
throw new OperationCanceledException();
- System.out.println("GC");
+ LOGGER.trace("GC");
SVGCache.getSVGUniverse().clearUnreferenced();
- SessionGarbageCollection.gc(null, sessionContext.getSession(), true, null);
+ SessionGarbageCollection.gc(null, exportPlan.sessionContext.getSession(), true, null);
System.gc();
- System.out.println("GC finished");
+ LOGGER.trace("GC finished");
progress.worked(1);
}
- } catch (DatabaseException e) {
- throw new PdfException(e);
- } catch (FileNotFoundException e) {
- throw new PdfException(e);
- } catch (DocumentException e) {
- throw new PdfException(e);
- } finally {
+
+ return exportedPages;
+ } catch (DatabaseException | FileNotFoundException | DocumentException | ExceptionConverter e) {
+ throw new PdfException(e);
+ } finally {
workerThread.stopDispatchingEvents(true);
- System.out.println("closing document");
+ LOGGER.trace("closing document");
try {
- if ( document!=null ) document.close();
- if ( writer!=null ) writer.close();
- } catch(RuntimeException e) {
- e.printStackTrace();
+ if ( document != null ) document.close();
+ if ( writer != null ) writer.close();
+ LOGGER.trace("document closed");
+ } catch (RuntimeException e) {
+ LOGGER.error("Error closing PDF document writer", e);
}
- System.out.println("document closed");
SessionGarbageCollectorJob.getInstance().setEnabled(true).scheduleAfterQuietTime();
}
}
return ret;
}
- public static String getCreator() {
- String creator = null;
- IProduct product = Platform.getProduct();
- if (product != null) {
- creator = product.getDescription();
- if (creator == null) {
- creator = product.getName();
- }
- }
- if (creator == null) {
- creator = "Simantics";
- }
- return creator;
- }
+ public static String getCreator() {
+ String creator = null;
+ IProduct product = Platform.getProduct();
+ if (product != null) {
+ creator = product.getDescription();
+ if (creator == null) {
+ creator = product.getName();
+ }
+ }
+ if (creator == null) {
+ creator = "Simantics";
+ }
+ return creator;
+ }
static {
- Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
}
\ No newline at end of file
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
- // Print pdf
- DiagramPrinter.printToPdf(monitor, exportPlan, exportPlan.exportLocation.toString(), exportPlan.selectedNodes, exportPlan.sessionContext);
-
+ DiagramPrinter.printToPdf(monitor, exportPlan, exportPlan.exportLocation.toString(), exportPlan.selectedNodes);
} catch (PdfException e) {
throw new InvocationTargetException(e);
} finally {
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - (#7084) page numbering
*******************************************************************************/
package org.simantics.modeling.ui.pdf;
import org.simantics.db.common.NamedResource;
import org.simantics.db.management.ISessionContext;
+import org.simantics.export.core.pdf.PageNumbering;
import org.simantics.modeling.requests.CollectionResult;
import org.simantics.modeling.requests.Node;
import org.simantics.project.IProject;
* <code>true</code> to attach Wiki page.
*/
public boolean attachWiki = false;
-
-
+
+ /**
+ * Whether or not to add page numbers to the exported PDF. Default value is
+ * {@value #addPageNumbers}.
+ *
+ * @since 1.28.0
+ */
+ public boolean addPageNumbers = true;
+
+ /**
+ * This is ignored if {@link #addPageNumbers} is <code>false</code>.
+ */
+ public PageNumbering.Position pageNumberPosition = PageNumbering.Position.BOTTOM_RIGHT;
+
+ /**
+ * This is ignored if {@link #addPageNumbers} is <code>false</code>.
+ */
+ public PageNumbering.NumberingFormat pageNumberFormat = PageNumbering.NumberingFormat.PAGE_SLASH_TOTAL_PAGES;
+
+
public PDFExportPlan(ISessionContext sessionContext, Collection<String> recentLocations) {
this.sessionContext = sessionContext;
this.recentLocations = recentLocations;
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2017 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - (#7084) refactoring
*******************************************************************************/
package org.simantics.modeling.ui.pdf;
import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicReference;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
+import org.simantics.db.Session;
import org.simantics.db.common.request.PossibleIndexRoot;
import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.ValidationException;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
-import org.simantics.db.management.ISessionContext;
+import org.simantics.db.request.Read;
import org.simantics.diagram.elements.DiagramNodeUtil;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.g2d.canvas.Hints;
import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider;
import org.simantics.modeling.requests.Node;
import org.simantics.structural.stubs.StructuralResource2;
-import org.simantics.utils.DataContainer;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.page.PageDesc;
import org.simantics.utils.threads.IThreadWorkQueue;
*/
public class PDFPainter {
- public static boolean render(
+ public static void render(
final IThreadWorkQueue thread,
- final ISessionContext sessionContext,
PDFExportPlan exportModel,
final Node node,
final PdfWriter writer,
final PageDesc pageDesc,
final boolean fitDiagramContentsToPageMargins,
long timeout)
- throws InterruptedException, DatabaseException
+ throws InterruptedException, DatabaseException
{
- final DataContainer<Boolean> result = new DataContainer<Boolean>(false);
- final DataContainer<DatabaseException> exception = new DataContainer<DatabaseException>();
+ DatabaseException[] exception = { null };
+ ICanvasSceneGraphProvider[] sgProvider = { null };
- final CanvasContext ctx = new CanvasContext(thread);
- final AtomicReference<ICanvasSceneGraphProvider> sgProvider = new AtomicReference<ICanvasSceneGraphProvider>();
+ CanvasContext ctx = new CanvasContext(thread);
try {
final Semaphore done = new Semaphore(0);
// IMPORTANT: Load diagram in a different thread than the canvas context thread!
- ThreadUtils.getBlockingWorkExecutor().execute(new Runnable() {
- @Override
- public void run() {
- try {
- Pair<Resource, String> modelAndRVI = sessionContext.getSession().syncRequest(new UniqueRead<Pair<Resource, String>>() {
- @Override
- public Pair<Resource, String> perform(ReadGraph graph) throws DatabaseException {
- return new Pair<Resource, String>( resolveModel(graph, node), resolveRVI(graph, node) );
- }
- });
-
- final Boolean isSymbol = sessionContext.getSession().syncRequest(new UniqueRead<Boolean>() {
- @Override
- public Boolean perform(ReadGraph graph) throws DatabaseException {
- StructuralResource2 STR = StructuralResource2.getInstance(graph);
- DiagramResource DIA = DiagramResource.getInstance(graph);
- Resource possibleSymbol = graph.getPossibleObject(node.getDiagramResource(), STR.Defines);
- return possibleSymbol != null && graph.isInstanceOf(possibleSymbol, DIA.ElementClass);
- }
- });
-
- ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(ctx, modelAndRVI.first, node.getDiagramResource(), modelAndRVI.second, 5000);
- sgProvider.set( provider );
- ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
-
-// StringBuilder b = new StringBuilder();
-// NodeUtil.printTreeNodes(ctx.getCanvasNode(), b);
-// System.err.println(b.toString());
-
- ThreadUtils.asyncExec(thread, new Runnable() {
- @Override
- public void run() {
- try {
- PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol);
-
- chassis.paint(ctx, true);
- } finally {
- done.release();
- }
- }
- });
- } catch (DatabaseException e) {
- done.release();
- exception.set(e);
- } catch (Throwable e) {
- done.release();
- exception.set(new DatabaseException(e));
- } finally {
- done.release();
- }
+ ThreadUtils.getBlockingWorkExecutor().execute(() -> {
+ try {
+ Session s = exportModel.sessionContext.getSession();
+
+ Pair<Resource, String> modelAndRVI = s.syncRequest( modelAndRVI(node) );
+ Boolean isSymbol = s.syncRequest( isSymbol(node) );
+
+ ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(
+ ctx,
+ modelAndRVI.first,
+ node.getDiagramResource(),
+ modelAndRVI.second,
+ 5000);
+ sgProvider[0] = provider;
+ ctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, pageDesc);
+
+// System.err.println(NodeUtil.printTreeNodes(ctx.getCanvasNode(), new StringBuilder()).toString());
+
+ ThreadUtils.asyncExec(thread, () -> {
+ try {
+ PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol);
+ chassis.paint(ctx, true);
+ } catch (Throwable e) {
+ exception[0] = new DatabaseException(e);
+ } finally {
+ done.release();
+ }
+ });
+ } catch (DatabaseException e) {
+ done.release();
+ exception[0] = e;
+ } catch (Throwable e) {
+ done.release();
+ exception[0] = new DatabaseException(e);
+ } finally {
+ done.release();
}
});
done.acquire(2);
- if (exception.get() != null)
- throw exception.get();
- return result.get();
+ if (exception[0] != null)
+ throw exception[0];
} finally {
- if (sgProvider.get() != null)
- sgProvider.get().dispose();
+ if (sgProvider[0] != null)
+ sgProvider[0].dispose();
ctx.dispose();
}
}
+ private static Read<Pair<Resource, String>> modelAndRVI(Node node) {
+ return new UniqueRead<Pair<Resource, String>>() {
+ @Override
+ public Pair<Resource, String> perform(ReadGraph graph) throws DatabaseException {
+ return Pair.make( resolveModel(graph, node), resolveRVI(graph, node) );
+ }
+ };
+ }
+
+ private static Read<Boolean> isSymbol(Node node) {
+ return new UniqueRead<Boolean>() {
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ Resource possibleSymbol = graph.getPossibleObject(node.getDiagramResource(), STR.Defines);
+ return possibleSymbol != null && graph.isInstanceOf(possibleSymbol, DIA.ElementClass);
+ }
+ };
+ }
+
private static Resource resolveModel(ReadGraph graph, Node node) throws DatabaseException {
Resource composite = node.getDefiningResources().head();
Resource model = graph.syncRequest(new PossibleIndexRoot(composite));
-// Resource model = StructuralVariables.getModel(graph, composite);
if (model == null)
throw new ValidationException("no model found for composite " + NameUtils.getSafeName(graph, composite));
return model;
}
-// private static String resolveModelURI(ReadGraph graph, final Node node) throws DatabaseException {
-// return graph.getURI(resolveModel(graph, node));
-// }
-
private static String resolveRVI(ReadGraph graph, final Node node) throws DatabaseException {
- String RVI = node.getRVI();
- if(RVI != null) return RVI;
+ String RVI = node.getRVI();
+ if (RVI != null) return RVI;
Resource composite = node.getDefiningResources().head();
Variable var = Variables.getVariable(graph, composite);
org.simantics.db.layer0.variable.RVI rvi = var.getPossibleRVI(graph);
- if(rvi == null) return null;
- return rvi.toString();
-// final ResourceArray compositePath = StructuralVariables.getCompositeArray(graph, composite);
-// final ResourceArray variablePath = compositePath.removeFromBeginning(1);
-// return StructuralVariables.getRVI(graph, variablePath);
+ return rvi != null ? rvi.toString() : null;
}
-}
+}
\ No newline at end of file
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.simantics.databoard.container.FormatHandler;
import org.simantics.db.Resource;
import org.simantics.db.Session;
+import org.simantics.db.layer0.migration.MigratedImportResult;
import org.simantics.db.layer0.migration.MigrationUtils;
import org.simantics.db.layer0.util.DraftStatusBean;
import org.simantics.db.management.ISessionContext;
import org.simantics.project.ProjectKeys;
import org.simantics.ui.SimanticsUI;
import org.simantics.ui.utils.ResourceAdaptionUtils;
+import org.simantics.utils.strings.EString;
import org.simantics.utils.ui.ErrorLogger;
import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.utils.ui.dialogs.InfoDialog;
/**
* @author Tuukka Lehtonen
}
try {
+ MigratedImportResult[] result = { null };
getContainer().run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
Resource target = ResourceAdaptionUtils.toSingleResource(importModel.selection);
importModel.sessionContext.getSession().markUndoPoint();
- doImport(monitor, importModel.importLocation, importModel.sessionContext.getSession(), target);
+ result[0] = doImport(monitor, importModel.importLocation, importModel.sessionContext.getSession(), target);
} catch (Exception e) {
throw new InvocationTargetException(e);
} finally {
}
}
});
+
+ if (result[0].hasMissingExternals()) {
+ InfoDialog.open(getShell(), "Missing Externals Created",
+ "The system was unable to find some of the external entities referenced by the imported material. Place-holders have been created for the missing entities.\nThe missing entities are:\n"
+ + EString.implode(result[0].tgResult.missingExternals),
+ SWT.SHEET);
+ }
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
WizardPage cp = (WizardPage) getContainer().getCurrentPage();
return true;
}
- public static void doImport(IProgressMonitor monitor, File modelFile, Session session, Resource target)
+ public static MigratedImportResult doImport(IProgressMonitor monitor, File modelFile, Session session, Resource target)
throws Exception
{
SubMonitor mon = SubMonitor.convert(monitor);
mon.beginTask("Loading shared library from disk", 1000);
- FormatHandler<Object> handler1 = new FormatHandler<Object>() {
+ FormatHandler<MigratedImportResult> handler1 = new FormatHandler<MigratedImportResult>() {
@Override
public Binding getBinding() {
return TransferableGraph1.BINDING;
}
@Override
- public Object process(DataContainer container) throws Exception {
+ public MigratedImportResult process(DataContainer container) throws Exception {
mon.worked(100);
mon.setTaskName("Importing shared library into database");
Variant draftStatus = container.metadata.get(DraftStatusBean.EXTENSION_KEY);
TransferableGraph1 tg = (TransferableGraph1) container.content.getValue();
- MigrationUtils.importSharedOntology(mon.newChild(850, SubMonitor.SUPPRESS_NONE), session, tg, draftStatus == null);
- return null;
+ return MigrationUtils.importSharedOntology(mon.newChild(850, SubMonitor.SUPPRESS_NONE), session, tg, draftStatus == null);
}
};
- Map<String, FormatHandler<Object>> handlers = new HashMap<>();
+ Map<String, FormatHandler<MigratedImportResult>> handlers = new HashMap<>();
handlers.put(Constants.SHARED_LIBRARY_FORMAT_V1, handler1);
- DataContainers.readFile(modelFile, handlers);
+ MigratedImportResult result = DataContainers.readFile(modelFile, handlers);
mon.setTaskName("Postprocessing");
mon.subTask("");
mon.newChild(50).done();
+
+ return result;
}
}
org.simantics.scl.db;bundle-version="0.1.3",
org.simantics.selectionview.ontology;bundle-version="1.2.0",
org.simantics.scl.ui;bundle-version="0.5.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.apache.batik
Export-Package: org.simantics.modeling,
org.simantics.modeling.actions,
org.simantics.modeling.adapters,
include "Simantics/Datatypes"
include "Spreadsheet/All"
include "Simantics/WorkbenchSelection"
+include "Simantics/Workbench"
include "Simantics/Structural"
include "SWT/All"
include "Simantics/UI"
diagramsOf :: Model -> <ReadGraph> [Diagram]
diagramsOf model = recurse
DIA.Diagram
- (toResource (configurationOf model))
+ (configurationOf model)
where
recurse t r = do
- cs = resourceChildrenOf r
- dias = map fromResource $ filter isDiagramComposite cs
+ cs = children r
+ dias = filter isDiagramComposite cs
folders = filter (not . isDiagramComposite) cs
dias + concatMap (recurse t) folders
isDiagramComposite r = existsStatement r MOD.CompositeToDiagram
"""Returns a model relative path of the given diagram."""
pathOf :: Diagram -> <ReadGraph> [String]
-pathOf diagram = map nameOf $ unfoldl aux $ toResource diagram
+pathOf diagram = map nameOf $ unfoldl aux diagram
where
aux r = if existsStatement r SIMU.IsConfigurationOf
then Nothing
// @Private?
diagramResourceOf :: Diagram -> <ReadGraph> Resource
-diagramResourceOf d = singleObject (toResource d) MOD.CompositeToDiagram
+diagramResourceOf d = singleObject d MOD.CompositeToDiagram
import "Extras/HashMap" as Map
"""Creates or modifies an existing diagram to contain the given diagram elements."""
createDiagramR :: DiagramSpec -> (Dynamic -> <WriteGraph> Resource) -> [DiagramElement Resource] -> <WriteGraph> (Diagram, [Resource])
createDiagramR (ExistingDiagram diagram') joinMap elementSpecs = runProc do
- configuration = toResource diagram'
+ configuration = diagram'
diagram = compositeToDiagram' configuration
hasName = L0.HasName
componentMap = Map.fromList [ (c `relatedValue` hasName :: String, c)
- | c <- resourceChildrenOf configuration
+ | c <- children configuration
]
denyByPredicate diagram L0.ConsistsOf
elements = setElements (DiagramInfo diagram configuration componentMap) joinMap elementSpecs
elements = setElements (DiagramInfo diagram configuration (Map.create ())) joinMap elementSpecs
claimRelatedValue diagram DIA.HasModCount
(fromInteger (length elements) :: Long)
- (fromResource configuration, elements)
+ (configuration, elements)
) where
createConfiguration () = do
lastId = length path - 1
parentFolder = foldl (\p id -> getOrCreateFolder p (path!id))
- (toResource (configurationOf model))
+ (configurationOf model)
[0..lastId-1]
createComposite_ parentFolder (path!lastId) compositeType
getOrCreateFolder parentFolder name =
claimFolder model path folderType = do
lastId = length path
foldl (\p id -> getOrCreateFolder p folderType (path!id))
- (toResource (configurationOf model))
+ (configurationOf model)
[0..lastId-1]
claimModelFolder :: Model -> [String] -> Resource -> <Proc,WriteGraph> Resource
claimModelFolder model path folderType = do
lastId = length path
foldl (\p id -> getOrCreateFolder p folderType (path!id))
- (toResource model)
+ model
[0..lastId-1]
getOrCreateFolder :: Resource -> Resource -> String -> <Proc,WriteGraph> Resource
"""Returns a diagram in the given model with the given model relative path."""
diagram :: Model -> [String] -> <ReadGraph> Diagram
diagram model path =
- fromResource $ foldl
+ foldl
(\r name -> match possibleResourceChild r name with
Just c -> c
Nothing -> fail ("Didn't find " + name + ".")
)
- (toResource (configurationOf model)) path
+ (configurationOf model) path
possibleDiagram :: Model -> [String] -> <ReadGraph> (Maybe Diagram)
possibleDiagram model path =
- map fromResource (foldl
+ foldl
(\r name -> match r with
Just p -> possibleResourceChild p name
Nothing -> Nothing
)
- (Just $ toResource (configurationOf model)) path)
+ (Just (configurationOf model)) path
/*
"""FIXME: doesn't work anymore with the elementsOfR spec
syncActivateDiagram :: Diagram -> <WriteGraph, Proc> Boolean
syncActivateDiagram composite = do
- diagram = compositeToDiagram' $ toResource composite
+ diagram = compositeToDiagram' composite
syncActivateOnce diagram
True
createComposite__ :: Configuration -> String -> Resource -> <WriteGraph> Diagram
compositeToDiagram :: Resource -> <ReadGraph> Diagram
-compositeToDiagram c = fromResource (singleObject c MOD.CompositeToDiagram)
+compositeToDiagram c = singleObject c MOD.CompositeToDiagram
createComposite :: Configuration -> String -> Resource -> <WriteGraph> Diagram
createComposite diagramFolder name compositeType = do
- newName = findFreshName name (toResource diagramFolder)
+ newName = findFreshName name diagramFolder
createComposite__ diagramFolder newName compositeType
elementToComponent :: Element -> <ReadGraph> Component
-elementToComponent element = do
- component = singleObject (toResource element) MOD.ElementToComponent
- fromResource component
+elementToComponent element = singleObject element MOD.ElementToComponent
componentToElement :: Component -> <ReadGraph> Element
-componentToElement component = do
- element = singleObject (toResource component) MOD.ComponentToElement
- fromResource element
+componentToElement component = singleObject component MOD.ComponentToElement
getConnections :: Diagram -> <ReadGraph> [Resource]
-getConnections diagram = [object | object <- (toResource $ compositeToDiagram $ toResource diagram) # L0.ConsistsOf, isInstanceOf object DIA.RouteGraphConnection]
+getConnections diagram = [object | object <- (compositeToDiagram diagram) # L0.ConsistsOf, isInstanceOf object DIA.RouteGraphConnection]
getConnection :: Diagram -> String -> <ReadGraph> [Resource]
getConnection diagram name = do
$ sourceDiagram
for targetDiagrams $ \diagram ->
- syncActivateOnce $ toResource diagram
+ syncActivateOnce diagram
doElementPostProcessing elementMap elementPostProcessing
possibleDrawingTemplate :: Model -> Diagram -> <ReadGraph> Maybe Resource
possibleDrawingTemplate model d = do
d' = diagramResourceOf d
- library = fromJust $ possibleResourceChild (toResource model) "Diagram Templates"
+ library = fromJust $ possibleResourceChild model "Diagram Templates"
match (possibleObject d' TMPL.HasDrawingTemplate) with
Just dt -> match (possibleNameOf dt) with
Just name -> possibleResourceChild library name
()
getTargetComponent (targetDiagram :: Diagram) (sourceComponent :: Resource) =
- (possibleResourceChild (toResource targetDiagram) (fromJust $ possibleNameOf sourceComponent)) :: Maybe Resource
+ (possibleResourceChild targetDiagram (fromJust $ possibleNameOf sourceComponent)) :: Maybe Resource
translateDiagram2 (targetModel :: Model)
(sourceDiagram :: Diagram)
// FLAGS ---------------------------
+@deprecated "Unnecessary function."
toFlag :: Resource -> Flag
-toFlag flag = (fromResource flag)
+toFlag flag = flag
importJava "org.simantics.modeling.flags.MergeFlags" where
@JavaName mergeFlags
hasType STR.ConnectionJoin,
hasStatement
DIA.JoinsFlag
- (toResource flag1),
+ flag1,
hasStatement
DIA.JoinsFlag
- (toResource flag2)
+ flag2
]
()
+@deprecated "Unnecessary function."
flagToElement :: Flag -> Element
-flagToElement flag = do
- flagResource = toResource flag
- fromResource flagResource
+flagToElement flag = flag
getFlags :: Diagram -> <ReadGraph> [Resource]
getFlags dia = do
- children = collectionToList (objects_ (singleObject (toResource dia) MOD.CompositeToDiagram) L0.ConsistsOf)
+ children = collectionToList (objects_ (singleObject dia MOD.CompositeToDiagram) L0.ConsistsOf)
flags = filter (\x -> isInstanceOf x DIA.Flag) children
flags
type Severity = Resource
issuesOf :: Model -> <ReadGraph> [Issue]
-issuesOf model = recurse ISSUE.Issue (toResource model)
+issuesOf model = recurse ISSUE.Issue model
where
recurse t r = do
- cs = resourceChildrenOf r
- issues = map fromResource $ filter isIssue cs
+ cs = children r
+ issues = filter isIssue cs
issueGrp = filter (not . isIssue) cs
issues + concatMap (recurse t) issueGrp
isIssue r = isInstanceOf r ISSUE.Issue
"""
model :: String -> <ReadGraph> Model
model name = match possibleResourceChild (currentProject ()) name with
- Just m -> fromResource m
+ Just m -> m
Nothing -> fail $ "Didn't find a model " + name + "."
"""
and returns the `configuration` resource
"""
configurationOf :: Model -> <ReadGraph> Configuration
-configurationOf m = do
- conf = singleObject (toResource m) SIMU.HasConfiguration
- fromResource conf
+configurationOf m = singleObject m SIMU.HasConfiguration
"""
Returns the list of all models in the current project.
"""
allModels :: () -> <ReadGraph> [Model]
-allModels _ = map fromResource $ objectsWithType (currentProject ()) L0.ConsistsOf SIMU.Model
+allModels _ = objectsWithType (currentProject ()) L0.ConsistsOf SIMU.Model
importJava "org.simantics.modeling.ModelingUtils" where
"""Removes the index associated with the model."""
or error if failed
"""
+@deprecated "This function is equivalent to renameNode."
renameMBNode :: Resource -> String -> <WriteGraph> String
-renameMBNode entity newname = do
- renameNode (toResource entity) newname
+renameMBNode entity newname = renameNode entity newname
importJava "org.simantics.db.common.utils.NameUtils" where
@JavaName findFreshName
editNodeText :: ICanvasContext -> String -> String -> String -> <Proc> String
copyPaste :: ICanvasContext -> ICanvasContext -> [Resource] -> <Proc> Boolean
+
+ renderSVG :: ICanvasContext -> <Proc> String
getSceneGraphProvider :: Diagram -> <Proc> ICanvasSceneGraphProvider
getSceneGraphProvider diagram = do
- diagramName = syncRead(\() -> getSafeName (toResource diagram))
+ diagramName = syncRead(\() -> getSafeName diagram)
diagramRVI = "/" + diagramName
- model = syncRead(\() -> getPossibleModel (toResource diagram))
- composite = syncRead(\() -> compositeToDiagram' (toResource diagram))
+ model = syncRead(\() -> fromJust $ possibleIndexRoot diagram)
+ composite = syncRead(\() -> compositeToDiagram' diagram)
getICanvasSceneGraphProvider model composite diagramRVI
getDiagramContext :: ICanvasSceneGraphProvider -> ICanvasContext
getNodeTransform :: Diagram -> String -> <Proc> String
getNodeTransform diagram nodeName = do
- diagramName = syncRead(\() -> getSafeName (toResource diagram))
+ diagramName = syncRead(\() -> getSafeName diagram)
diagramRVI = "/" + diagramName
- model = syncRead(\() -> getPossibleModel (toResource diagram))
- composite = syncRead(\() -> compositeToDiagram' (toResource diagram))
+ model = syncRead(\() -> getPossibleModel diagram)
+ composite = syncRead(\() -> compositeToDiagram' diagram)
provider = getICanvasSceneGraphProvider model composite diagramRVI
context = getCanvasContext provider
getTransform context nodeName
getNodeText :: Diagram -> String -> <Proc> String
getNodeText diagram nodeName = do
- diagramName = syncRead(\() -> getSafeName (toResource diagram))
+ diagramName = syncRead(\() -> getSafeName diagram)
diagramRVI = "/" + diagramName
- model = syncRead(\() -> getPossibleModel (toResource diagram))
- composite = syncRead(\() -> compositeToDiagram' (toResource diagram))
+ model = syncRead(\() -> getPossibleModel diagram)
+ composite = syncRead(\() -> compositeToDiagram' diagram)
provider = getICanvasSceneGraphProvider model composite diagramRVI
context = getCanvasContext provider
getText context nodeName
getNodeCount :: Diagram -> <Proc> String
getNodeCount diagram = do
- diagramName = syncRead(\() -> getSafeName (toResource diagram))
+ diagramName = syncRead(\() -> getSafeName diagram)
diagramRVI = "/" + diagramName
- model = syncRead(\() -> getPossibleModel (toResource diagram))
- composite = syncRead(\() -> compositeToDiagram' (toResource diagram))
+ model = syncRead(\() -> getPossibleModel diagram)
+ composite = syncRead(\() -> compositeToDiagram' diagram)
provider = getICanvasSceneGraphProvider model composite diagramRVI
context = getCanvasContext provider
getCount context
stepExperiment :: IExperiment -> Double -> <Proc> ()
simulateExperiment :: IExperiment -> Boolean -> <Proc> ()
disposeExperiment :: IExperiment -> <Proc> ()
- possibleActiveRunVariable ::Resource -> <ReadGraph> Variable
+ getExperimentState :: IExperiment -> <ReadGraph> ExperimentState
+ possibleActiveRunVariable ::Resource -> <ReadGraph> Maybe Variable
importJava "org.simantics.simulation.experiment.IExperiment" where
data IExperiment
+
+importJava "org.simantics.simulation.experiment.ExperimentState" where
+ data ExperimentState
+ INITIALIZING, RUNNING, STOPPED, DISPOSED :: ExperimentState
experimentFromRun :: Variable -> <ReadGraph> IExperiment
experimentFromRun run = (run#iExperiment) :: IExperiment
\ No newline at end of file
"""
subscriptionFoldersOf :: Model -> <ReadGraph> [SubscriptionFolder]
-subscriptionFoldersOf model = recurse (toResource model)
+subscriptionFoldersOf model = recurse model
where
- recurse r = do
- cs = resourceChildrenOf r
- folders = map fromResource $ filter isSubscriptionFolder cs
- folders
+ recurse r = filter isSubscriptionFolder (children r)
isSubscriptionFolder r = isInstanceOf r MOD.Subscription
include "Simantics/Model"
import "Simantics/Diagram"
import "Simantics/Flag"
+import "Simantics/Workbench"
include "Simantics/Ontologies"
type UserComponent = Resource
configurationOfComponentType :: UserComponent -> <ReadGraph> Resource
configurationOfComponentType component = do
- config = singleObject (toResource component) STR.IsDefinedBy
+ config = singleObject component STR.IsDefinedBy
config
importJava "org.simantics.modeling.flags.LiftFlag" where
flagToTerminal :: Flag -> <WriteGraph> Resource
flagToTerminal flag = do
- result = liftFlag (toResource flag)
+ result = liftFlag flag
if result == Nothing
- then singleObject (toResource flag) DIA.IsLiftedAs
- else do
- show result
- (toResource flag)
-
+ then singleObject flag DIA.IsLiftedAs
+ else flag
+
+@deprecated "Calling this function is unnecessary."
configToDiagram :: Resource -> Diagram
-configToDiagram config = do
- fromResource config
+configToDiagram config = config
populateTerminalToSymbol :: Resource -> (Double, Double) -> <WriteGraph> Element
-populateTerminalToSymbol terminal (x, y) = do
+populateTerminalToSymbol terminal (x, y) = element
+ where
uc = singleObject terminal L0.PartOf
symbol = singleObject uc MOD.ComponentTypeToSymbol
diagram = singleObject symbol STR.IsDefinedBy
(toDoubleArray [1,0,0,1,x,y])
addToGraph diagram terminal element
addCommentMetadata ("Populated terminal " + (show element) + " to user component " + (show uc))
- (fromResource element)
+
importJava "org.simantics.modeling.symbolEditor.PopulateTerminal" where
addToGraph :: Resource -> Resource -> Resource -> <WriteGraph> ()
claimRelatedValue script L0.HasName scriptName
claimRelatedValue script STR.ComponentTypeScript.type scriptType
claimRelatedValue script STR.ComponentTypeScript.code scriptCode
+
+@private
+possibleSubstructure :: Resource -> <ReadGraph> Maybe Resource
+possibleSubstructure element = do
+ match possibleObject element MOD.ElementToComponent with
+ Nothing -> Nothing
+ Just component -> match possibleTypeOf component STR.Component with
+ Nothing -> Nothing
+ Just componentType -> match possibleObject componentType STR.IsDefinedBy with
+ Nothing -> Nothing
+ Just configuration -> Just configuration
+
+@private
+possibleSubstructureEditor :: Resource -> <ReadGraph,Proc> Maybe (Resource,EditorAdapter)
+possibleSubstructureEditor element = match possibleSubstructure element with
+ Nothing -> Nothing
+ Just configuration -> do
+ adapters = editorAdapters configuration
+ if(length adapters > 0) then Just (configuration, adapters!0) else Nothing
+
+navigateToSubstructureAction :: Resource -> <Proc> ()
+navigateToSubstructureAction element = do
+ match (syncRead (\x -> possibleSubstructureEditor element)) with
+ Nothing -> ()
+ Just (configuration,editor) -> openEditor editor configuration
+
\ No newline at end of file
--- /dev/null
+import "Simantics/DB"
+
+importJava "org.simantics.ui.workbench.editor.EditorAdapter" where
+ data EditorAdapter
+ openEditor :: EditorAdapter -> a -> <Proc> ()
+
+importJava "org.simantics.ui.workbench.editor.EditorRegistry" where
+
+ @private
+ @JavaName getInstance
+ getEditorRegistryInstance :: IEditorRegistry
+
+importJava "org.simantics.ui.workbench.editor.IEditorRegistry" where
+ data IEditorRegistry
+
+ @private
+ @JavaName getAdaptersFor
+ editorAdapters_ :: IEditorRegistry -> a -> <ReadGraph> Vector EditorAdapter
+
+editorAdapters :: a -> <ReadGraph> [EditorAdapter]
+editorAdapters object = vectorToList $ editorAdapters_ getEditorRegistryInstance object
import org.simantics.db.layer0.request.PossibleModel;
import org.simantics.db.layer0.util.ClipboardUtils;
import org.simantics.db.layer0.util.DraftStatusBean;
+import org.simantics.db.layer0.util.ExternalDownloadBean;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
import org.simantics.db.layer0.util.PasteEventHandler;
TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
monitor.worked(95);
+
+ Variant edb = tg.extensions.get(ExternalDownloadBean.EXTENSION_KEY);
+ if(edb != null) {
+ metadata.put(ExternalDownloadBean.EXTENSION_KEY, edb);
+ }
monitor.setTaskName("Writing transferable graph...");
DataContainers.writeFile(location, new DataContainer(
package org.simantics.modeling;
+import java.awt.Dimension;
+import java.awt.RenderingHints;
+import java.awt.RenderingHints.Key;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Set;
+import java.util.UUID;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.batik.dom.GenericDOMImplementation;
+import org.apache.batik.svggen.SVGGeneratorContext;
+import org.apache.batik.svggen.SVGGraphics2D;
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
import org.simantics.diagram.elements.DiagramNodeUtil;
import org.simantics.g2d.utils.CanvasUtils;
import org.simantics.scenegraph.ParentNode;
import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.G2DRenderingHints;
import org.simantics.scenegraph.g2d.G2DSceneGraph;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.g2d.IG2DNodeVisitor;
import org.simantics.scenegraph.g2d.events.command.Commands;
import org.simantics.scenegraph.g2d.nodes.BackgroundNode;
import org.simantics.scenegraph.g2d.nodes.BoundsNode;
import org.simantics.scenegraph.g2d.nodes.DataNode;
import org.simantics.scenegraph.g2d.nodes.DecorationSVGNode;
import org.simantics.scenegraph.g2d.nodes.NavigationNode;
+import org.simantics.scenegraph.g2d.nodes.SVGNode;
import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
import org.simantics.scenegraph.utils.NodeUtil;
import org.simantics.trend.impl.ItemNode;
import org.simantics.utils.threads.ThreadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
public class SCLScenegraph {
-
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SCLScenegraph.class);
+
public static ICanvasSceneGraphProvider getICanvasSceneGraphProvider(Resource model, Resource diagram, String diagramRVI) throws DatabaseException, InterruptedException {
ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(model, diagram, diagramRVI);
return provider;
provider.dispose();
}
- //public static Resource getDiagramRuntime(Resource )
-
-
-// public static String getNodeTransform(ICanvasContext ctx, String name) throws DatabaseException, InterruptedException {
-// return getNodeTransform(ctx, name);
-// }
-
public static String getNodeTransform(ICanvasContext ctx, String name) {
Set<TextNode> texts = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
}
}
- public static boolean copyPaste (final ICanvasContext source_ctx, final ICanvasContext target_ctx, List<Resource> modules) throws DatabaseException {
+ public static boolean copyPaste (final ICanvasContext source_ctx, final ICanvasContext target_ctx, List<Resource> modules) throws DatabaseException {
IDiagram idiagram = source_ctx.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM);
return true;
}
+ static class Generator extends SVGGraphics2D {
+
+ int elemLevel = 0;
+ String newElementId = null;
+ ArrayList<Element> elements = new ArrayList<Element>();
+
+ public static final String svgNS = "http://www.w3.org/2000/svg";
+
+ public Generator(SVGGeneratorContext ctx, boolean joku) {
+ super(ctx, joku);
+ }
+
+ public Generator(Document document) {
+ super(document);
+ }
+
+ @Override
+ public Element getRoot() {
+ Element root = super.getRoot();
+ for(Element e : elements) {
+ root.appendChild(e);
+ }
+ return root;
+ }
+
+ @Override
+ public void setRenderingHint(Key arg0, Object arg1) {
+ if(G2DRenderingHints.KEY_BEGIN_ELEMENT == arg0) {
+ elemLevel++;
+ }
+ if(G2DRenderingHints.KEY_ELEMENT_ID == arg0) {
+ if(arg1 != null)
+ newElementId = arg1.toString();
+ else
+ newElementId = UUID.randomUUID().toString();
+ }
+ if(G2DRenderingHints.KEY_END_ELEMENT == arg0) {
+ elemLevel--;
+ if(elemLevel == 0) {
+ Element group = getDOMFactory().createElement(SVG_G_TAG);
+ //Element group = getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG);
+ group.setAttributeNS(null, "id", newElementId);
+ group.setAttributeNS(null, "class", arg1.toString());
+ getRoot(group);
+ elements.add(group);
+ }
+ }
+ super.setRenderingHint(arg0, arg1);
+ }
+
+ }
+
+ public static Element renderSVGNode(IG2DNode node) {
+
+ // Get a DOMImplementation.
+ DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
+
+ // Create an instance of org.w3c.dom.Document.
+ String svgNS = "http://www.w3.org/2000/svg";
+ Document document = domImpl.createDocument(svgNS, "svg", null);
+
+ SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);
+ ctx.setComment(null);
+
+ // Create an instance of the SVG Generator.
+ SVGGraphics2D svgGenerator = new Generator(ctx, false);
+
+ try {
+
+ svgGenerator.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ svgGenerator.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ svgGenerator.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ node.render(svgGenerator);
+
+ } catch (Throwable t) {
+ LOGGER.error("Problems rendering scene graph to SVG", t);
+ }
+
+ return svgGenerator.getRoot();
+ }
+
+ public static String printSVGDocument(Element doce) {
+
+ StringBuilder result = new StringBuilder();
+
+ NodeList nl = doce.getChildNodes();
+
+ for(int i=0;i<nl.getLength();i++) {
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ try {
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+ transformer.transform(new DOMSource(nl.item(i)),
+ new StreamResult(new OutputStreamWriter(os, "UTF-8")));
+
+ os.flush();
+ os.close();
+
+ } catch (Throwable t) {
+ LOGGER.error("Problems formatting SVGDocument to text.", t);
+ }
+
+ result.append(new String(os.toByteArray()));
+
+ }
+
+ return result.toString();
+
+ }
+
+ public static String renderSVG(ICanvasContext ctx) {
+
+ // Get a DOMImplementation.
+ DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
+
+ // Create an instance of org.w3c.dom.Document.
+ String svgNS = "http://www.w3.org/2000/svg";
+ Document document = domImpl.createDocument(svgNS, "svg", null);
+
+ // Create an instance of the SVG Generator.
+ SVGGraphics2D svgGenerator = new Generator(document);
+
+ StringBuilder b = new StringBuilder();
+
+ try {
+
+ G2DSceneGraph sg = ctx.getSceneGraph();
+ G2DParentNode root = (G2DParentNode) sg.getRootNode();
+
+ // rtree is the actual content of the diagram
+ RTreeNode rtree = NodeUtil.getNearestChildByClass(root, RTreeNode.class);
+ Rectangle2D rtreeBounds = NodeUtil.getLocalBounds(rtree);
+
+ // nav is a node that has zooming functionalities
+ NavigationNode nav = NodeUtil.getNearestChildByClass(root, NavigationNode.class);
+ nav.setZoomEnabled(true);
+
+ // fit view with the contents of rtreeBounds
+ nav.zoomTo(rtreeBounds);
+
+ // get the bounds of the content
+ Rectangle2D content = NodeUtil.getLocalBounds(nav);
+
+ svgGenerator.scale(3,3);
+
+ // translate svgGenerator to the x and y coordinates of current content
+ svgGenerator.translate(-1 * content.getX(), (-1 * content.getY()));
+
+ Rectangle2D destination = new Rectangle2D.Double(0,0,1000,1000);
+ double sx = destination.getWidth() / content.getWidth();
+ double sy = destination.getHeight() / content.getHeight();
+ double scale = sx < sy ? sx : sy;
+
+ // Set svgCanvasSize to the given size parameters
+ svgGenerator.setSVGCanvasSize(new Dimension((int)(scale * content.getWidth()), (int)(scale * content.getHeight())));
+ svgGenerator.setClip(content);
+
+ double trX = -1 * content.getX();
+ double trY = -1 * content.getY();
+
+ b.append("<svg width=\"100%\" height=\"100%\" stroke=\"black\"><g transform=\"translate(").append(trX).append(' ').append(trY).append(")\">");
+
+ IG2DNodeVisitor visitor = new IG2DNodeVisitor() {
+
+ int indent = 0;
+
+ HashMap<IG2DNode,Integer> enters = new HashMap<>();
+
+ @Override
+ public void enter(IG2DNode node) {
+ indent++;
+ if(node instanceof ConnectionNode) {
+ Element doc = renderSVGNode((IG2DNode)node);
+ String svg = printSVGDocument(doc);
+ b.append(svg);
+ } else if (node instanceof SVGNode) {
+ SVGNode svg = (SVGNode)node;
+ b.append(svg.getSVGText());
+ } else if (node instanceof G2DParentNode) {
+ AffineTransform at = node.getTransform();
+ if(node instanceof SingleElementNode) {
+ SingleElementNode sen = (SingleElementNode)node;
+ if(sen.getKey() != null) {
+ String key = sen.getKey().toString();
+ b.append("\n<g class=\"definedElement\" id=\"" + key + "\">");
+ }
+ }
+ if(!at.isIdentity()) {
+ if(at.getScaleX() == 1.0 && at.getScaleY() == 1.0 && at.getShearX() == 0.0 && at.getShearY() == 0.0) {
+ String m = "translate(" + at.getTranslateX() + " " + at.getTranslateY() + ")";
+ b.append("\n<g transform=\"" + m + "\">");
+ } else {
+ double[] ds = new double[6];
+ at.getMatrix(ds);
+ String m = "matrix(" + ds[0] + " " + ds[1] + " " + ds[2] + " " + ds[3] + " " + ds[4] + " " + ds[5] + ")";
+ b.append("\n<g transform=\"" + m + "\">");
+ }
+ }
+ }
+
+ enters.put(node, b.length());
+
+ }
+
+ @Override
+ public void leave(IG2DNode node) {
+ if(node instanceof ConnectionNode || node instanceof SVGNode) {
+ // We are done
+ } else if (node instanceof G2DParentNode) {
+ AffineTransform at = node.getTransform();
+ if(!at.isIdentity()) {
+ b.append("</g>");
+ }
+ if(node instanceof SingleElementNode) {
+ SingleElementNode sen = (SingleElementNode)node;
+ if(sen.getKey() != null) {
+ int enterLength = enters.get(node);
+ if(b.length() == enterLength) {
+ Element doc = renderSVGNode((IG2DNode)node);
+ String svg = printSVGDocument(doc);
+ b.append(svg);
+ }
+ b.append("</g>");
+ }
+ }
+ }
+ indent --;
+ }
+
+ };
+ sg.accept(visitor);
+
+ } catch (Throwable t) {
+ LOGGER.error("Problems rendering canvas context to SVG", t);
+ }
+
+ b.append("</g></svg>");
+ //System.err.println(" == FINAL RESULT == ");
+ //System.err.println(b);
+ return b.toString();
+
+ }
+
}
\ No newline at end of file
public class Activator implements BundleActivator {
+ private static BundleContext context;
+
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void start(BundleContext context) throws Exception {
+ Activator.context = context;
Hashtable properties = new Hashtable();
context.registerService(ModuleSourceRepository.class, OntologyModuleSourceRepository.INSTANCE, properties);
public void stop(BundleContext context) throws Exception {
}
-
+ public static BundleContext getContext() {
+ return context;
+ }
}
*******************************************************************************/
package org.simantics.modeling.mapping;
-import gnu.trove.map.hash.THashMap;
-
import java.util.Map;
+import java.util.function.BiFunction;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.diagram.synchronization.graph.GraphCopyAdvisor;
import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;
import org.simantics.layer0.Layer0;
-import org.simantics.utils.datastructures.BinaryFunction;
+
+import gnu.trove.map.hash.THashMap;
/**
* @author Tuukka Lehtonen
* Diagram mapping will have problems and potentially break the
* configuration if the type is not the same as in the source.
*/
- BinaryFunction<StatementEvaluation, ReadGraph, Statement> statementAdvisor =
- new BinaryFunction<StatementEvaluation, ReadGraph, Statement>() {
+ BiFunction<ReadGraph, Statement, StatementEvaluation> statementAdvisor =
+ new BiFunction<ReadGraph, Statement, StatementEvaluation>() {
@Override
- public StatementEvaluation call(ReadGraph graph, Statement stm) {
+ public StatementEvaluation apply(ReadGraph graph, Statement stm) {
if (DIA.HasFlagType.equals(stm.getPredicate()))
return StatementEvaluation.INCLUDE;
if (G2D.HasFontStyle.equals(stm.getPredicate()))
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function1;
import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class CompileSCLMonitorRequest extends AbstractExpressionCompilationRequest<CompilationContext, Variable> {
-
+
+ private static Logger LOGGER = LoggerFactory.getLogger(CompileSCLMonitorRequest.class);
+
protected static Name BROWSE = Name.create("Simantics/Variables", "browse");
protected static Name VALUE = Name.create("Simantics/Variables", "value");
sclContext.put("graph", graph);
return exp.apply(context.getParent(graph));
} catch (DatabaseException e) {
- e.printStackTrace();
throw (DatabaseException)e;
} catch (Throwable t) {
- t.printStackTrace();
throw new DatabaseException(t);
} finally {
sclContext.put("graph", oldGraph);
try {
return Environments.getType(context.runtimeEnvironment.getEnvironment(), valueType);
} catch (SCLExpressionCompilationException e) {
- e.printStackTrace();
+ LOGGER.warn("getExpectedType failed for valueType: " + valueType, e);
}
}
return super.getExpectedType(graph, context);
import org.simantics.db.request.Read;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingUtils;
+import org.simantics.modeling.internal.Activator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
import org.simantics.scl.compiler.source.ModuleSource;
import org.simantics.scl.compiler.source.StringModuleSource;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
+import org.simantics.scl.osgi.internal.OsgiJavaReferenceValidatorFactory;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.tuple.Tuple0;
import org.simantics.structural2.utils.StructuralUtils;
public enum GraphModuleSourceRepository implements ModuleSourceRepository {
INSTANCE;
+
+ private static final OsgiJavaReferenceValidatorFactory REFERENCE_VALIDATOR_FACTORY = new OsgiJavaReferenceValidatorFactory(Activator.getContext().getBundle());
@Override
public ModuleSource getModuleSource(final String moduleName, UpdateListener listener) {
e.printStackTrace();
}
}
+
+ @Override
+ public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
+ return REFERENCE_VALIDATOR_FACTORY;
+ }
}
static class ReadModuleSource extends UnaryRead<String, ModuleSource> {
public String toString() {
return new StringBuilder().append("OntologyModule ").append(getName()).toString();
}
+
+ @Override
+ public ClassLoader getParentClassLoader() {
+ return getClass().getClassLoader();
+ }
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
return false;
}
- private Collection<IProjectFeatureExtension> sortTopologically(Collection<IProjectFeatureExtension> toSort) {
- ArrayList<IProjectFeatureExtension> sorted = new ArrayList<IProjectFeatureExtension>(toSort);
- Collections.sort(sorted, new Comparator<IProjectFeatureExtension>() {
- Set<IProjectFeatureExtension> visited = new HashSet<IProjectFeatureExtension>();
- @Override
- public int compare(IProjectFeatureExtension e1, IProjectFeatureExtension e2) {
- visited.clear();
- if (deepRequires(visited, e1, e2))
- return 1;
- visited.clear();
- if (deepRequires(visited, e2, e1))
- return -1;
- return 0;
+ private void requiresDFS(IProjectFeatureExtension ext, ArrayList<IProjectFeatureExtension> result, Set<IProjectFeatureExtension> visited) {
+ if(visited.add(ext)) {
+ Set<IProjectFeatureExtension> reqs = required.getValues(ext);
+ if(reqs != null) {
+ for(IProjectFeatureExtension req : reqs) {
+ requiresDFS(req, result, visited);
+ }
}
- });
- return sorted;
+ result.add(ext);
+ }
+ }
+
+ private Collection<IProjectFeatureExtension> sortTopologically(Collection<IProjectFeatureExtension> toSort) {
+ ArrayList<IProjectFeatureExtension> result = new ArrayList<>();
+ Set<IProjectFeatureExtension> visited = new HashSet<>();
+ for(IProjectFeatureExtension ext : toSort) {
+ requiresDFS(ext, result, visited);
+ }
+ return result;
}
private Collection<IProjectFeatureExtension> requiredExtensions(IProjectFeatureExtension[] allExtensions, Collection<IProjectFeatureExtension> includedExtensions) throws ProjectException {
if (injectionTargetExt != null) {
changed = true;
includedProjectFeatureIds.add(ext.getId());
- result.add(ext);
+ if(!result.contains(ext))
+ result.add(ext);
required.add(injectionTargetExt, ext);
}
}
String description = StringUtils.safeString(el.getAttribute("description"));
boolean published = "true".equalsIgnoreCase(el.getAttribute("published"));
Collection<ProjectFeatureReference> requires = readProjectFeatureReferenceCollection(el, "requires");
- Collection<InjectedDependency> injections = readInjectedDependencies(el);
+ Collection<InjectedDependency> injections = readInjectedDependencies(el, id);
Collection<GroupReference> installGroups = readGroupReferenceCollection(el, "installGroup");
ProjectFeatureExtension ext = new ProjectFeatureExtension(el, id, label, description, published, requires, injections, installGroups);
this.extensions = newExtensions.toArray(new IProjectFeatureExtension[newExtensions.size()]);
}
- private Collection<InjectedDependency> readInjectedDependencies(IConfigurationElement element) {
+ private Collection<InjectedDependency> readInjectedDependencies(IConfigurationElement element, String id) {
Collection<InjectedDependency> result = new ArrayList<InjectedDependency>();
for (IConfigurationElement child : element.getChildren(INJECT_DEPENDENCY)) {
- String id = StringUtils.safeString(child.getAttribute("id"));
- if (id.isEmpty())
- // Invalid extension
- return null;
-
String targetId = StringUtils.safeString(child.getAttribute("targetId"));
if (targetId.isEmpty())
// Invalid extension
return null;
+
+ result.add(new InjectedDependency(new ProjectFeatureReference(id, false), new ProjectFeatureReference(targetId, false)));
+
}
return result;
org.simantics.basicexpression;bundle-version="1.1.0",
org.simantics.scenegraph;bundle-version="1.1.1",
org.eclipse.core.runtime;bundle-version="3.6.0",
- org.simantics.diagram.ontology;bundle-version="1.1.1"
+ org.simantics.diagram.ontology;bundle-version="1.1.1",
+ org.simantics.db.common
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.simantics.scenegraph.profile.impl.Activator
Import-Package: org.simantics
--- /dev/null
+package org.simantics.scenegraph.profile.request;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.layer0.Layer0;
+
+public class AvailableProfiles extends ResourceRead<List<NamedResource>>{
+
+ protected AvailableProfiles(Resource runtimeDiagram) {
+ super(runtimeDiagram);
+ }
+
+ @Override
+ public List<NamedResource> perform(ReadGraph graph) throws DatabaseException {
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ String indexURI = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasModelURI);
+ if (indexURI == null)
+ return Collections.emptyList();
+
+ Resource index = graph.getPossibleResource(indexURI);
+ if (index == null)
+ return Collections.emptyList();
+
+ Instances query = graph.adapt(DIA.Profile, Instances.class);
+
+ ArrayList<NamedResource> result = new ArrayList<>();
+ for(Resource profile : query.find(graph, index)) {
+ if(!graph.hasStatement(profile, L0.Abstract)) {
+ String name = graph.getRelatedValue(profile, L0.HasName, Bindings.STRING);
+ result.add(new NamedResource(name, profile));
+ }
+ }
+
+ return result;
+
+ }
+
+}
\ No newline at end of file
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.diagram.stubs.DiagramResource;
ArrayList<Resource> result = new ArrayList<Resource>();
Resource activeProfile = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasRuntimeProfile);
- if (activeProfile == null)
- return result;
+ if (activeProfile == null) {
+
+ List<NamedResource> available = graph.syncRequest(new AvailableProfiles(resource));
+ if(available.size() != 1) return result;
+
+ activeProfile = available.iterator().next().getResource();
+
+ }
Resource rootEntries = graph.getPossibleObject(activeProfile, DIA.HasEntries);
if (rootEntries == null)
updateHeader(cell, ((Header) elem).name);
} else if (elem instanceof Class<?>) {
Class<?> clazz = (Class<?>) elem;
- updateHeader(cell, clazz.getSimpleName());
+ updateHeader(cell, clazz.getSimpleName() + " (" + clazz.getPackage().getName() + ")");
}
}
if (rootPane != null)
rootPane.setCursor(cursor);
}
+
+ public void accept(IG2DNodeVisitor visitor) {
+ visitor.enter(this);
+ visitor.leave(this);
+ }
}
g2d.setTransform(ot);
}
+ @Override
+ public void accept(IG2DNodeVisitor visitor) {
+ visitor.enter(this);
+ for (IG2DNode node : getSortedNodes()) {
+ if (node.validate()) {
+ node.accept(visitor);
+ }
+ }
+ visitor.leave(this);
+ }
+
/**
* Return the IDs of the children of this node in ascending Z order. This
* method will always allocate a new result list and sort it. To get the IDs
package org.simantics.scenegraph.g2d;
import java.awt.Component;
-import java.awt.RenderingHints.Key;
import java.awt.geom.Rectangle2D;
+import java.util.Map;
/**
* @author Tuukka Lehtonen
*/
public final class G2DRenderingHints {
+ public static final Key KEY_BEGIN_ELEMENT = new G2DRenderingHints.Key(0);
+ public static final Key KEY_END_ELEMENT = new G2DRenderingHints.Key(1);
+ public static final Key KEY_ELEMENT_ID = new G2DRenderingHints.Key(2);
+
+ public static class Key extends java.awt.RenderingHints.Key {
+
+ public Key(int privateKey) {
+ super(privateKey);
+ }
+
+ @Override
+ public boolean isCompatibleValue(Object val) {
+ switch (intKey()) {
+ case 0:
+ return val == null || val instanceof String
+ || val instanceof Map;
+ case 1:
+ return val == null || val instanceof Object;
+ case 2:
+ return val == null || val instanceof Object;
+ default:
+ throw new RuntimeException("Not possible!");
+ }
+ }
+ }
+
/**
* A rendering hint for storing the boundaries of the control area within a
* Graphics2D instance.
*/
public void render(Graphics2D g2d);
+ /**
+ * Visit the IG2DNode substructure of this node using the provided visitor.
+ *
+ * @param visitor the visitor to use
+ * @since 1.29.0
+ */
+ public void accept(IG2DNodeVisitor visitor);
+
/**
* Mark the scene graph to be repainted in its current rendering context (UI
* component) as soon as is appropriate for the backend system.
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.scenegraph.g2d;
+
+/**
+ * @author Antti Villberg
+ * @since 1.29.0
+ */
+public interface IG2DNodeVisitor {
+
+ public void enter(IG2DNode node);
+ public void leave(IG2DNode node);
+
+}
void getTreePath(INode node, ArrayList<INode> result) {
result.clear();
- for (INode parent = node.getParent(); parent != null; parent = parent.getParent())
- result.add(parent);
+ for (; node != null; node = node.getParent())
+ result.add(node);
}
void notSameGraph(INode o1, INode o2) {
ArrayList<INode> path1 = tmp.path1;
ArrayList<INode> path2 = tmp.path2;
- // Get path to root node for both nodes
- INode o1 = (INode) e1;
- INode o2 = (INode) e2;
- getTreePath(o1, path1);
- getTreePath(o2, path2);
+ try {
+ // Get path to root node for both nodes
+ getTreePath((INode) e1, path1);
+ getTreePath((INode) e2, path2);
- // Sanity checks: nodes part of same scene graph
- INode root1 = path1.isEmpty() ? o1 : path1.get(path1.size() - 1);
- INode root2 = path2.isEmpty() ? o2 : path2.get(path2.size() - 1);
- if (root1 != root2)
- notSameGraph(o1, o2);
+ // Sanity checks: nodes part of same scene graph
+ if (path1.get(path1.size() - 1) != path2.get(path2.size() - 1))
+ notSameGraph((INode)e1, (INode)e2);
- try {
// Find first non-matching nodes in the paths starting from the root node
int i1 = path1.size() - 1;
int i2 = path2.size() - 1;
if (i2 < 0)
return Order.ASCENDING == order ? 1 : -1;
- INode n1 = path1.get(i1);
- INode n2 = path2.get(i2);
- IG2DNode g1 = n1 instanceof IG2DNode ? (IG2DNode) n1 : null;
- IG2DNode g2 = n2 instanceof IG2DNode ? (IG2DNode) n2 : null;
- if (g1 != null && g2 != null) {
- int z1 = g1.getZIndex();
- int z2 = g2.getZIndex();
- int c = compare(z1, z2);
- return order == Order.ASCENDING ? c : -c;
- }
- // Can't sort non-IG2DNodes.
- return 0;
+ return compare(path1.get(i1), path2.get(i2));
} finally {
// Don't hold on to objects unnecessarily
path1.clear();
path2.clear();
}
}
-
- private int compare(int v1, int v2) {
- return v1 < v2 ? -1 : (v1 > v2 ? 1 : 0);
+
+ private int compare(INode n1, INode n2) {
+ if(n1 instanceof IG2DNode) {
+ if(n2 instanceof IG2DNode) {
+ int z1 = ((IG2DNode)n1).getZIndex();
+ int z2 = ((IG2DNode)n2).getZIndex();
+ int c = Integer.compare(z1, z2);
+ return order == Order.ASCENDING ? c : -c;
+ }
+ else
+ return -1; // sort IG2DNodes before non-IG2DNodes
+ }
+ else {
+ if(n2 instanceof IG2DNode)
+ return 1;
+ else
+ return 0; // all non-IG2DNodes are equal in comparison
+ }
}
};
import java.awt.Color;
import java.awt.Composite;
+import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Point2D;
import org.simantics.diagram.connection.RouteGraph;
import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.G2DRenderingHints;
import org.simantics.scenegraph.g2d.IG2DNode;
import org.simantics.scenegraph.g2d.events.MouseEvent;
import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode;
return false;
}
+ @Override
+ public void beforeRender(Graphics2D g) {
+ g.setRenderingHint(G2DRenderingHints.KEY_BEGIN_ELEMENT, "connection");
+ }
+
+ @Override
+ public void afterRender(Graphics2D g) {
+ g.setRenderingHint(G2DRenderingHints.KEY_END_ELEMENT, "connection");
+ }
+
}
if (data == null)
return null;
+ SVGUniverse univ = SVGCache.getSVGUniverse();
try {
- SVGUniverse univ = SVGCache.getSVGUniverse();
- synchronized(univ) {
- // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
- byte[] dataBytes = data.getBytes("UTF-8");
- dataHash = digest(dataBytes, assignments);
- if (diagramCache != null)
- univ.decRefCount(diagramCache.getXMLBase());
- URI uri = univ.loadSVG(new ByteArrayInputStream(dataBytes), dataHash);
- diagramCache = univ.getDiagram(uri, false);
- if (diagramCache != null) {
- if (diagramCache.getRoot() == null) {
- diagramCache = univ.getDiagram(univ.loadSVG(BROKEN_SVG_DATA), false);
- dataHash = "broken";
- } else if (diagramCache.getRoot().getBoundingBox().isEmpty()) {
- diagramCache = univ.getDiagram(univ.loadSVG(EMPTY_SVG_DATA), false);
- dataHash = "empty";
- } else {
- for(SVGNodeAssignment ass : assignments) {
- SVGElement e = diagramCache.getElement(ass.elementId);
- if(e != null) {
- if("$text".equals(ass.attributeNameOrId)) {
- Tspan t = (Tspan)e;
- t.setText(ass.value);
- Text text = (Text)t.getParent();
- text.rebuild();
- } else {
- e.setAttribute(ass.attributeNameOrId, AnimationElement.AT_AUTO, ass.value);
- }
- }
- }
- if(!assignments.isEmpty())
- diagramCache.updateTime(0);
- }
- }
- documentCache = data;
- if (diagramCache != null) {
- setBounds((Rectangle2D) diagramCache.getRoot().getBoundingBox().clone());
- univ.incRefCount(diagramCache.getXMLBase());
- } else {
- setBounds(new Rectangle2D.Double());
- }
- }
+ Rectangle2D bbox = null;
+ synchronized (univ) {
+ // Relinquish reference to current element
+ if (diagramCache != null) {
+ univ.decRefCount(diagramCache.getXMLBase());
+ diagramCache = null;
+ }
+
+ // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
+ byte[] dataBytes = data.getBytes("UTF-8");
+ dataHash = digest(dataBytes, assignments);
+ URI uri = univ.loadSVG(new ByteArrayInputStream(dataBytes), dataHash);
+ diagramCache = univ.getDiagram(uri, false);
+
+ if (diagramCache != null) {
+ univ.incRefCount(diagramCache.getXMLBase());
+
+ if (diagramCache.getRoot() == null) {
+ univ.decRefCount(diagramCache.getXMLBase());
+ diagramCache = univ.getDiagram(univ.loadSVG(BROKEN_SVG_DATA), false);
+ dataHash = "broken";
+ univ.incRefCount(diagramCache.getXMLBase());
+ bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone();
+ } else {
+ bbox = diagramCache.getRoot().getBoundingBox();
+ if (bbox.isEmpty()) {
+ univ.decRefCount(diagramCache.getXMLBase());
+ diagramCache = univ.getDiagram(univ.loadSVG(EMPTY_SVG_DATA), false);
+ dataHash = "empty";
+ univ.incRefCount(diagramCache.getXMLBase());
+ bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone();
+ } else {
+ if (applyAssignments(diagramCache, assignments)) {
+ bbox = (Rectangle2D) diagramCache.getRoot().getBoundingBox().clone();
+ } else {
+ bbox = (Rectangle2D) bbox.clone();
+ }
+ }
+ }
+ } else {
+ bbox = new Rectangle2D.Double();
+ }
+ }
+
+ documentCache = data;
+ setBounds(bbox);
} catch (SVGException e) {
- setBounds((Rectangle2D) diagramCache.getViewRect().clone());
+ // This can only occur if diagramCache != null.
+ setBounds(diagramCache.getViewRect(new Rectangle2D.Double()));
+ univ.decRefCount(diagramCache.getXMLBase());
+ diagramCache = null;
} catch (IOException e) {
diagramCache = null;
}
return dataHash;
}
+ private static boolean applyAssignments(SVGDiagram diagram, List<SVGNodeAssignment> assignments) throws SVGException {
+ if (assignments.isEmpty())
+ return false;
+ boolean changed = false;
+ for (SVGNodeAssignment ass : assignments) {
+ SVGElement e = diagram.getElement(ass.elementId);
+ if (e != null) {
+ if ("$text".equals(ass.attributeNameOrId)) {
+ if (e instanceof Tspan) {
+ Tspan t = (Tspan) e;
+ t.setText(ass.value);
+ SVGElement parent = t.getParent();
+ if (parent instanceof Text)
+ ((Text) parent).rebuild();
+ changed = true;
+ }
+ } else {
+ e.setAttribute(ass.attributeNameOrId, AnimationElement.AT_AUTO, ass.value);
+ changed = true;
+ }
+ }
+ }
+ diagram.updateTime(0);
+ return changed;
+ }
+
public static Rectangle2D getBounds(String data) {
- return getBounds(data, null);
+ return getBounds(data, null);
}
public static Rectangle2D getBounds(String data, List<SVGNodeAssignment> assignments) {
}
return rect;
} catch (SVGException e) {
- return ((Rectangle2D) diagramCache.getViewRect().clone());
+ return diagramCache.getViewRect(new Rectangle2D.Double());
} catch(IOException e) {
}
return null;
URI uri = univ.loadSVG(new ByteArrayInputStream(dataBytes), digest);
diagramCache = univ.getDiagram(uri, false);
if (diagramCache != null) {
- SVGRoot root = diagramCache.getRoot();
+ SVGRoot root = diagramCache.getRoot();
if (root == null) return new Rectangle2D.Double();
return (Rectangle2D)root.getBoundingBox().clone();
}
}
} catch (SVGException e) {
- return ((Rectangle2D) diagramCache.getViewRect().clone());
+ return diagramCache.getViewRect(new Rectangle2D.Double());
} catch(IOException e) {
}
return null;
this.setTransform(new AffineTransform(data));
}
+ public String getSVGText() {
+ String ret = data.replace("<svg", "<g").replaceAll("svg>", "g>");
+ //return diagramCache.toString();
+ //return data.replace("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\"", "<g").replaceAll("svg>", "/g>");
+ return ret;
+ }
+
}
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import org.simantics.scenegraph.g2d.G2DRenderingHints;
import org.simantics.scenegraph.g2d.IG2DNode;
import org.simantics.scenegraph.g2d.events.EventTypes;
import org.simantics.scenegraph.g2d.events.MouseEvent;
protected Composite composite;
protected Boolean visible = Boolean.TRUE;
protected Boolean hidden = Boolean.FALSE;
+ private transient Object key;
+
+ public void setKey(Object key) {
+ this.key = key;
+ }
+
+ public Object getKey() {
+ return key;
+ }
public void setTransferableProvider(TransferableProvider transferableProvider) {
if (transferableProvider != this.transferableProvider) {
return EventTypes.MouseDragBeginMask;
}
+ public void beforeRender(Graphics2D g) {
+ g.setRenderingHint(G2DRenderingHints.KEY_BEGIN_ELEMENT, "definedElement");
+ }
+
+ public void afterRender(Graphics2D g) {
+ g.setRenderingHint(G2DRenderingHints.KEY_END_ELEMENT, "definedElement");
+ }
+
}
*******************************************************************************/
package org.simantics.scenegraph.g2d.nodes;
+import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
public class UnboundedNode extends SingleElementNode {
return null;
}
+ @Override
+ public void beforeRender(Graphics2D g) {
+ }
+
+ @Override
+ public void afterRender(Graphics2D g) {
+ }
+
}
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Function;
import org.simantics.scenegraph.IDynamicSelectionPainterNode;
import org.simantics.scenegraph.ILookupService;
printSceneGraph(System.out, 0, node);
}
+ @FunctionalInterface
public static interface NodeProcedure<T> {
T execute(INode node, String id);
}
return result;
}
+ /**
+ * Recursively iterates through all child nodes of the specified node and
+ * for those nodes that are of class <code>ofClass</code>, invokes
+ * <code>consumer</code>.
+ *
+ * @param node
+ * @param ofClass
+ * @param consumer
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends INode> INode forChildrenDeep(INode node, Class<T> ofClass, Function<T, INode> func) {
+ return forChildrenDeep(node, n -> ofClass.isInstance(n) ? func.apply((T) n) : null);
+ }
+
+ public static <T extends INode> INode forChildrenDeep(INode node, Function<INode, INode> func) {
+ INode ret = func.apply(node);
+ if (ret != null)
+ return ret;
+
+ if (node instanceof ParentNode<?>) {
+ if (node instanceof G2DParentNode) {
+ G2DParentNode g2dpn = (G2DParentNode) node;
+ for (IG2DNode n : g2dpn.getSortedNodes()) {
+ INode r = forChildrenDeep(n, func);
+ if (r != null) {
+ return r;
+ }
+ }
+ } else {
+ for (INode n : ((ParentNode<?>) node).getNodes()) {
+ INode r = forChildrenDeep(n, func);
+ if (r != null) {
+ return r;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
public static final int countTreeNodes(INode node) {
int result = 1;
if (node instanceof ParentNode<?>) {
return result;
}
- public static final void printTreeNodes(INode node, StringBuilder builder) {
+ public static final StringBuilder printTreeNodes(INode node, StringBuilder builder) {
printTreeNodes(node, 0, builder);
+ return builder;
}
- public static final void printTreeNodes(INode node, int indent, StringBuilder builder) {
+ public static final StringBuilder printTreeNodes(INode node, int indent, StringBuilder builder) {
for (int i = 0; i < indent; i++)
builder.append(" ");
builder.append(node.toString() + "\n");
printTreeNodes(n, indent+2, builder);
}
}
+ return builder;
}
public static final <T extends INode> Set<T> collectNodes(INode node, Class<T> clazz) {
org.simantics.scl.compiler.types.kinds,
org.simantics.scl.compiler.types.util
Bundle-ClassPath: .
-Service-Component: OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml
+Service-Component: OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml,
+ OSGI-INF/org.simantics.scl.compiler.elaboration.java.LoggingModule.xml
Import-Package: org.osgi.service.component.annotations
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.simantics.scl.compiler.elaboration.java.LoggingModule">
+ <implementation class="org.simantics.scl.compiler.elaboration.java.LoggingModule"/>
+</scr:component>
\ No newline at end of file
output.. = bin/
bin.includes = META-INF/,\
.,\
- OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml
+ OSGI-INF/org.simantics.scl.compiler.source.repository.BuiltinModuleSourceRepository.xml,\
+ OSGI-INF/org.simantics.scl.compiler.elaboration.java.LoggingModule.xml
import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
+import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader;
import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
import gnu.trove.map.hash.THashMap;
public class DeclarationClassification {
+ DModuleHeader moduleHeader;
ArrayList<ImportDeclaration> importsAst = new ArrayList<ImportDeclaration>();
ArrayList<DDataAst> dataTypesAst = new ArrayList<DDataAst>();
ArrayList<DTypeAst> typeAliasesAst = new ArrayList<DTypeAst>();
handle((DMappingRelationAst)declaration);
else if(declaration instanceof DRelationAst)
handle((DRelationAst)declaration);
+ else if(declaration instanceof DModuleHeader)
+ handle((DModuleHeader)declaration);
else
throw new InternalCompilerError("Unknown declaration " + declaration.getClass().getSimpleName());
}
mappingRelationsAst.add(declaration);
}
+ public void handle(DModuleHeader declaration) {
+ moduleHeader = declaration;
+ }
+
public void addValueDocumentation(String valueName, DDocumentationAst documentation) {
DDocumentationAst oldDoc = valueDocumentation.put(valueName, documentation);
if(oldDoc != null) {
import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
import org.simantics.scl.compiler.internal.codegen.utils.Constants;
import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
+import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
import org.simantics.scl.compiler.internal.parsing.types.TypeAst;
import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.module.ImportDeclaration;
+import org.simantics.scl.compiler.module.InvalidModulePathException;
+import org.simantics.scl.compiler.module.ModuleUtils;
import org.simantics.scl.compiler.module.repository.ImportFailure;
import org.simantics.scl.compiler.module.repository.ImportFailureException;
import org.simantics.scl.compiler.types.TCon;
private final CompilationContext compilationContext;
private final ErrorLog errorLog;
private final String moduleName;
+ private final ModuleHeader moduleHeader;
private final ArrayList<ImportDeclaration> importsAst;
+ private final JavaReferenceValidatorFactory jrvFactory;
final JavaReferenceValidator<Object, Object, Object, Object> javaReferenceValidator;
private final ValueRepository valueDefinitionsAst;
private final RelationRepository relationDefinitionsAst;
THashMap<String, ClassRef> classRefs = new THashMap<String, ClassRef>();
THashMap<String, BranchPoint[]> branchPoints;
- @SuppressWarnings("unchecked")
public Elaboration(CompilationContext compilationContext, CompilationTimer timer, EnvironmentFactory localEnvironmentFactory,
- String moduleName, ArrayList<ImportDeclaration> importsAst,
- JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
+ String moduleName, ModuleHeader moduleHeader, ArrayList<ImportDeclaration> importsAst,
+ JavaReferenceValidatorFactory jrvFactory,
ValueRepository valueDefinitionsAst,
RelationRepository relationDefinitionsAst) {
this.compilationContext = compilationContext;
this.errorLog = compilationContext.errorLog;
this.moduleName = moduleName;
+ this.moduleHeader = moduleHeader;
importsAst = processRelativeImports(importsAst);
this.importsAst = importsAst;
- this.javaReferenceValidator = (JavaReferenceValidator<Object, Object, Object, Object>)javaReferenceValidator;
+ this.jrvFactory = jrvFactory;
+ this.javaReferenceValidator = moduleHeader == null || moduleHeader.classLoader == null
+ ? jrvFactory.getDefaultJavaReferenceValidator()
+ : jrvFactory.getJavaReferenceValidator(moduleHeader.classLoader);
+ if(javaReferenceValidator == null)
+ errorLog.log(moduleHeader.classLoaderLocation, "Didn't find the specified class loader.");
this.valueDefinitionsAst = valueDefinitionsAst;
this.relationDefinitionsAst = relationDefinitionsAst;
ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
for(ImportDeclaration relativeImport : relativeImports) {
if(relativeImport.moduleName.startsWith(".")) {
- String absoluteModuleName = convertRelativeModulePath(relativeImport.location, relativeImport.moduleName);
- if(absoluteModuleName != null) {
+ try {
+ String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName);
ImportDeclaration absoluteImport = new ImportDeclaration(
absoluteModuleName, relativeImport.localName,
relativeImport.reexport, relativeImport.spec);
absoluteImport.location = relativeImport.location;
absoluteImports.add(absoluteImport);
- }
+ } catch (InvalidModulePathException e) {
+ errorLog.log(relativeImport.location, e.getMessage());
+ }
}
else
absoluteImports.add(relativeImport);
return absoluteImports;
}
- private String convertRelativeModulePath(long location, String relativeModuleName) {
- String originalRelativeModuleName = relativeModuleName;
- int p = moduleName.lastIndexOf('/');
- String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
- while(relativeModuleName.startsWith(".")) {
- if(relativeModuleName.startsWith("./")) {
- relativeModuleName = relativeModuleName.substring(2);
- }
- else if(relativeModuleName.startsWith("../")) {
- relativeModuleName = relativeModuleName.substring(3);
- if(parentPackage.isEmpty()) {
- errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
- return null;
- }
- p = parentPackage.lastIndexOf('/');
- parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
- }
- else {
- errorLog.log(location, "Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
- return null;
- }
- }
- return parentPackage + "/" + relativeModuleName;
- }
-
public void addTypesToEnvironment(
ArrayList<DDataAst> dataTypesAst,
ArrayList<DTypeAst> typeAliasesAst,
if(annotations != null) {
for(DAnnotationAst annotation : annotations)
if(annotation.id.text.equals("@JavaName")) {
- Expression p0 = annotation.parameters[0];
- if(p0 instanceof EVar)
- javaName = ((EVar)p0).name;
- else if(p0 instanceof ELiteral) {
- ELiteral lit = (ELiteral)p0;
- javaName = ((StringConstant)lit.getValue()).getValue();
- }
+ String temp = AnnotationUtils.processStringAnnotation(errorLog, annotation);
+ if(temp != null)
+ javaName = temp;
}
else if(annotation.id.text.equals("@private")) {
+ AnnotationUtils.processTagAnnotation(errorLog, annotation);
isPrivate = true;
}
}
import org.simantics.scl.compiler.environment.EnvironmentFactory;
import org.simantics.scl.compiler.errors.ErrorLog;
import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
+import org.simantics.scl.compiler.internal.header.ModuleHeader;
import org.simantics.scl.compiler.internal.parsing.declarations.DeclarationAst;
import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
+import org.simantics.scl.compiler.internal.parsing.parser.SCLParserOptions;
import org.simantics.scl.compiler.module.ConcreteModule;
import org.simantics.scl.compiler.module.options.ModuleCompilationOptions;
import org.simantics.scl.compiler.top.ModuleInitializer;
private CompilationTimer timer;
private ModuleCompilationOptions options;
- public SCLCompiler(ModuleCompilationOptions options) {
+ JavaReferenceValidatorFactory jrvFactory;
+
+ public SCLCompiler(ModuleCompilationOptions options, JavaReferenceValidatorFactory jrvFactory) {
this.options = options == null ? ModuleCompilationOptions.STANDARD_OPTIONS : options;
+ this.jrvFactory = jrvFactory;
}
@SuppressWarnings("unchecked")
if(SCLCompilerConfiguration.ENABLE_TIMING) initializeTiming();
try {
SCLParserImpl parser = new SCLParserImpl(sourceReader);
+ parser.setParserOptions(SCLParserOptions.MODULE_DEFAULT);
if(!parser.isEmpty())
for(DeclarationAst declaration : (ArrayList<DeclarationAst>)parser.parseModule())
declarations.handle(declaration);
public void compile(
EnvironmentFactory localEnvironmentFactory,
- String moduleName,
- JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator) {
+ String moduleName) {
try {
if(hasErrors()) return;
Elaboration elaboration = new Elaboration(compilationContext,
timer,
localEnvironmentFactory,
moduleName,
+ ModuleHeader.process(compilationContext.errorLog, declarations.moduleHeader),
declarations.importsAst,
- javaReferenceValidator,
+ jrvFactory,
declarations.valueDefinitionsAst,
declarations.relationDefinitionsAst);
if(options.computeCoverage)
codeGeneration.externalConstants);
module.setClasses(classes);
+ module.setParentClassLoader(elaboration.javaReferenceValidator.getClassLoader());
module.setModuleInitializer(moduleInitializer);
module.setBranchPoints(elaboration.branchPoints);
if(compilationContext.errorLog.hasErrorsOrWarnings())
import org.simantics.scl.compiler.elaboration.expressions.EStringLiteral;
import org.simantics.scl.compiler.elaboration.expressions.EVar;
import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
public class AnnotationUtils {
+ /**
+ * Processes an annotation of form
+ * <pre>@Annotation "text"</pre>
+ * or
+ * <pre>@Annotation text</pre>
+ */
+ public static String processStringAnnotation(ErrorLog errorLog, DAnnotationAst annotation) {
+ if(annotation.parameters.length != 1)
+ errorLog.log(annotation.location, "Expected one string parameter for " + annotation.id.text);
+ String result = extractString(annotation.parameters[0]);
+ if(result == null)
+ errorLog.log(annotation.location, "Expected a string parameter for " + annotation.id.text);
+ return result;
+ }
+
+ public static void processTagAnnotation(ErrorLog errorLog, DAnnotationAst annotation) {
+ if(annotation.parameters.length != 0)
+ errorLog.log(annotation.location, "Expected no parameters for " + annotation.id.text);
+ }
+
public static String extractString(Expression expression) {
if(expression instanceof EVar)
return ((EVar)expression).name;
addValue("visitBranchPoint", VisitBranchPoint.INSTANCE);
}
+
+ setParentClassLoader(getClass().getClassLoader());
}
@Override
"java/lang/Object", "hashCode", Types.NO_EFFECTS, Types.INTEGER, A));
addValue("toString", new JavaMethod(true,
"java/lang/Object", "toString", Types.NO_EFFECTS, Types.STRING, A));
+
+ setParentClassLoader(getClass().getClassLoader());
}
static Expression createLiteral(FunctionValue value) {
--- /dev/null
+package org.simantics.scl.compiler.elaboration.java;
+
+import org.cojen.classfile.TypeDesc;
+import org.osgi.service.component.annotations.Component;
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.JavaMethod;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.internal.codegen.types.StandardTypeConstructor;
+import org.simantics.scl.compiler.module.ConcreteModule;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+public class LoggingModule extends ConcreteModule {
+
+ private static String[] LOGGING_METHODS = new String[] {
+ "trace", "debug", "info", "warn", "error"
+ };
+
+ public LoggingModule() {
+ super("Logging");
+
+ // Logger
+ TCon Logger = Types.con(getName(), "Logger");
+ StandardTypeConstructor loggerConstructor = new StandardTypeConstructor(Logger, Kinds.STAR, TypeDesc.forClass(Logger.class));
+ loggerConstructor.external = true;
+ addTypeDescriptor("Logger", loggerConstructor);
+
+ // Common types
+ Type loggingType = Types.functionE(Types.STRING, Types.PROC, Types.UNIT);
+
+ // Add logging methods
+ for(String methodName : LOGGING_METHODS) {
+ JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", methodName, Types.PROC, Types.UNIT, Logger, Types.STRING);
+ SCLValue value = new SCLValue(Name.create(getName(), methodName));
+ value.setType(loggingType);
+ value.setMacroRule(new MacroRule() {
+ @Override
+ public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ ConcreteModule module = context.getCompilationContext().module;
+ apply.set(new ELiteral(javaMethod), new Expression[] {
+ new EExternalConstant(LoggerFactory.getLogger(module.getName().replaceAll("/", ".")), Logger),
+ apply.parameters[0]
+ });
+ return apply;
+ }
+ });
+ addValue(value);
+ }
+
+ setParentClassLoader(LoggerFactory.class.getClassLoader());
+ }
+
+}
return new ResourceAttribute(name);
}
});
+ setParentClassLoader(getClass().getClassLoader());
}
private static class ResourceAttribute implements SCLEntityType.Attribute {
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.Constant;
+import org.simantics.scl.compiler.constants.NoRepConstant;
import org.simantics.scl.compiler.constants.SCLConstant;
import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext;
import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.SSAUtils;
import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
context.markModified("improve-parameters");
}
+ private static Constant getOnlyPossibleValue(Type type) {
+ type = Types.canonical(type);
+ if(type == Types.UNIT)
+ return NoRepConstant.UNIT;
+ else if(type == Types.PUNIT)
+ return NoRepConstant.PUNIT;
+ return null;
+ }
+
private boolean tryToImproveParameter(int position) {
BoundVar parameter = parameters[position];
- Val constant = null;
- ValRef constantRef = null;
- for(ContRef ref = getOccurrence(); ref != null; ref = ref.getNext()) {
- Jump jump = (Jump)ref.getParent();
- ValRef valRef = jump.getParameters()[position];
- Val val = valRef.getBinding();
- if(val == parameter)
- continue;
- if(constant == null) {
- constant = val;
- constantRef = valRef;
- continue;
+ Constant onlyPossibleValue = getOnlyPossibleValue(parameter.getType());
+ if(onlyPossibleValue == null) {
+ Val constant = null;
+ ValRef constantRef = null;
+ for(ContRef ref = getOccurrence(); ref != null; ref = ref.getNext()) {
+ Jump jump = (Jump)ref.getParent();
+ ValRef valRef = jump.getParameters()[position];
+ Val val = valRef.getBinding();
+ if(val == parameter)
+ continue;
+ if(constant == null) {
+ constant = val;
+ constantRef = valRef;
+ continue;
+ }
+ if(val != constant)
+ return false;
}
- if(val != constant)
- return false;
+ if(constant == null)
+ return false; // This is a strange case, because we cannot get the parameter anywhere
+ parameter.replaceBy(constantRef);
+ }
+ else {
+ parameter.replaceBy(onlyPossibleValue);
}
- if(constant == null)
- return false; // This is a strange case, because we cannot get the parameter anywhere
- parameter.replaceBy(constantRef);
for(ContRef ref = getOccurrence(); ref != null; ref = ref.getNext()) {
Jump jump = (Jump)ref.getParent();
return result;
}
+ /*
+ * This method assumes that the exit of the block is Jump.
+ */
private boolean optimizeTailSelfCall() {
- Jump jump = (Jump)exit;
- if(jump.getTarget().getBinding() != parent.returnCont)
- return false;
- if(jump.getParameters().length != 1)
- return false;
+ // The last statement of the block is LetApply that calls the parent function with right number of parameters
if(lastStatement == null || !(lastStatement instanceof LetApply))
return false;
LetApply apply = (LetApply)lastStatement;
- SSABlock initialBlock = parent.firstBlock;
- if(initialBlock.parameters.length != apply.getParameters().length)
- return false;
Val function = apply.getFunction().getBinding();
if(function != parent.target)
return false;
+ SSABlock initialBlock = parent.firstBlock;
+ if(initialBlock.parameters.length != apply.getParameters().length)
+ return false;
+
+ // The jump is a return (with one parameter)
+ // The parameter of the jump is the target of LetApply
+ Jump jump = (Jump)exit;
+ Cont targetCont = jump.getTarget().getBinding();
+ if(targetCont != parent.returnCont) {
+ SSABlock targetBlock = (SSABlock)targetCont;
+ if(targetBlock.firstStatement != null)
+ return false;
+ if(!(targetBlock.exit instanceof Jump))
+ return false;
+ Jump targetJump = (Jump)targetBlock.exit;
+ if(targetJump.getTarget().getBinding() != parent.returnCont)
+ return false;
+ if(targetJump.getParameters().length != 1)
+ return false;
+
+ BoundVar applyTarget = apply.getTarget();
+ ValRef targetJumpParameter = targetJump.getParameter(0);
+ isSameParam: if(!SSAUtils.representSameValue(applyTarget, targetJumpParameter)) {
+ BoundVar[] targetBlockParameters = targetBlock.getParameters();
+ for(int i=0;i<targetBlockParameters.length;++i) {
+ if(targetJumpParameter.getBinding() == targetBlockParameters[i]
+ && jump.getParameter(i).getBinding() == applyTarget)
+ break isSameParam;
+ }
+ return false;
+ }
+ }
+ else {
+ if(jump.getParameters().length != 1)
+ return false;
+ if(!SSAUtils.representSameValue(apply.getTarget(), jump.getParameter(0)))
+ return false;
+ }
// Do modifications
apply.detach();
apply.getFunction().remove();
jump.getTarget().remove();
jump.setTarget(initialBlock.createOccurrence());
+ for(ValRef parameter : jump.getParameters())
+ parameter.remove();
jump.setParameters(apply.getParameters());
return true;
}
+ /**
+ * Assumes that this block has no statements, the block is not the first block
+ * and the exit of the block is Jump.
+ */
private boolean etaBlock(SSASimplificationContext context) {
Jump jump = (Jump)exit;
if(parameters.length != jump.getParameters().length)
block.detach();
jump.destroy();
- setExit(block.exit);
+ setExit(block.exit);
/*System.out.println(">> AFTER INLINE >>");
System.out.println(getParent());
import org.cojen.classfile.TypeDesc;
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.constants.NoRepConstant;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont;
public void simplify(SSASimplificationContext context) {
for(SSABlock block = firstBlock; block != null; block = block.next)
block.simplify(context);
- if(firstBlock == lastBlock && firstBlock.firstStatement == firstBlock.lastStatement &&
- firstBlock.firstStatement instanceof LetFunctions) {
- simplifySingleLambda(context);
+ if(firstBlock == lastBlock && firstBlock.firstStatement == firstBlock.lastStatement) {
+ if(firstBlock.firstStatement instanceof LetApply)
+ simplifySingleApply(context);
+ else if(firstBlock.firstStatement instanceof LetFunctions)
+ simplifySingleLambda(context);
}
}
+
+ /**
+ * Simplifies the following kind of function definition
+ * \x -> f x
+ * to
+ * f
+ */
+ private void simplifySingleApply(SSASimplificationContext context) {
+ if(!(parent instanceof LetFunctions) || parent.getFirstClosure().next != null)
+ return;
+ LetApply apply = (LetApply)firstBlock.firstStatement;
+ if(!(firstBlock.exit instanceof Jump))
+ return;
+ Jump exit = (Jump)firstBlock.exit;
+ if(exit.getTarget().getBinding() != returnCont)
+ return;
+ if(exit.getParameter(0).getBinding() != apply.getTarget())
+ return;
+ BoundVar[] functionParameters = getParameters();
+ ValRef[] applyParameters = apply.getParameters();
+ if(functionParameters.length > applyParameters.length)
+ return;
+ int extraApplyParameters = applyParameters.length - functionParameters.length;
+ for(int i=0;i<functionParameters.length;++i)
+ if(!representSameValues(functionParameters[i], applyParameters[extraApplyParameters+i]))
+ return;
+ for(int i=0;i<extraApplyParameters;++i) {
+ Val b = applyParameters[i].getBinding();
+ if(b instanceof BoundVar) {
+ BoundVar bv = (BoundVar)b;
+ if(bv == target || bv.getParent() == firstBlock)
+ return;
+ }
+ }
+ if(!(target instanceof BoundVar))
+ return;
+
+ // Transform
+
+ LetFunctions binder = (LetFunctions)parent;
+ SSAFunction parentFunction = binder.getParentFunction();
+ if(extraApplyParameters > 0) {
+ //System.out.println("-------------------------------------------------------------");
+ //System.out.println(parentFunction);
+ //System.out.println("-------------------------------------------------------------");
+ apply.setTarget((BoundVar)target);
+ apply.setParameters(Arrays.copyOf(applyParameters, extraApplyParameters));
+ apply.insertBefore(binder);
+ binder.detach();
+ //System.out.println(parentFunction);
+ //System.out.println("-------------------------------------------------------------");
+ }
+ else {
+ binder.detach();
+ ((BoundVar)target).replaceBy(apply.getFunction());
+ }
+ context.markModified("SSAFunction.eta-reduce");
+ }
+
+ private boolean representSameValues(BoundVar boundVar, ValRef valRef) {
+ Val val = valRef.getBinding();
+ if(val == boundVar && valRef.getTypeParameters().length == 0)
+ return true;
+ if(val instanceof NoRepConstant && Types.equals(valRef.getType(), boundVar.getType()))
+ return true;
+ return false;
+ }
+
+ /**
+ * Simplifies the following kind of function definition
+ * \x -> \y -> e
+ * to
+ * \x y -> e
+ */
private void simplifySingleLambda(SSASimplificationContext context) {
LetFunctions letF = (LetFunctions)firstBlock.firstStatement;
if(!(letF.getFirstClosure() instanceof SSAFunction))
lastBlock = f.lastBlock;
firstBlock.firstStatement = firstBlock.lastStatement = null;
- setReturnCont(f.getReturnCont());
+ setReturnCont(f.getReturnCont());
effect = f.effect;
BoundVar[] newParameters = BoundVar.copy(f.firstBlock.parameters);
firstBlock.setParameters(BoundVar.concat(getParameters(), newParameters));
import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
import org.simantics.scl.compiler.constants.BooleanConstant;
import org.simantics.scl.compiler.constants.IntegerConstant;
+import org.simantics.scl.compiler.constants.NoRepConstant;
import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef;
import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
context.markModified("switch-to-if");
newExit.simplify(context);
}
- else if(branches.length == 1 && branches[0].constructor == null) {
+ else if(branches.length == 1 && isConstructorParameterless(branches[0])) {
scrutinee.remove();
getParent().setExit(new Jump(branches[0].cont));
}
}
+
+ private static boolean isConstructorParameterless(BranchRef branch) {
+ return branch.constructor == null || branch.constructor instanceof NoRepConstant;
+ }
@Override
public void collectFreeVariables(SSAFunction function,
public boolean isPublic(Object clazz) {
return false;
}
+
+ @Override
+ public ClassLoader getClassLoader() {
+ throw new UnsupportedOperationException();
+ }
}
* class is not found.
*/
ClassRef getClassRef(String className);
+
+ ClassLoader getClassLoader();
}
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.types;
+
+public interface JavaReferenceValidatorFactory {
+ JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(String context);
+ JavaReferenceValidator<Object, Object, Object, Object> getDefaultJavaReferenceValidator();
+}
public Class<?> findClass(TypeDesc name) {
return name.toClass(classLoader);
}
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
}
tsmb.finish();
}
- if(generateEqualsAndHashCode) {
- // Create equals
- {
- TypeDesc CLASS = TypeDesc.forClass(Class.class);
+ if(generateEqualsAndHashCode)
+ implementHashCodeAndEquals(classBuilder, recordName, fieldNamePrefix, types);
+ }
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
- LocalVariable parameter = tsmb.getParameter(0);
- Label success = tsmb.createLabel();
- Label failure = tsmb.createLabel();
+ public static void implementHashCodeAndEquals(ClassBuilder classBuilder, String recordName, String fieldNamePrefix, TypeDesc[] types) {
+ // Create equals
+ {
+ TypeDesc CLASS = TypeDesc.forClass(Class.class);
- // Check type
- tsmb.loadThis();
- tsmb.loadLocal(parameter);
- tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
- tsmb.loadLocal(parameter);
- tsmb.ifNullBranch(failure, true);
- tsmb.loadLocal(parameter);
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadThis();
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.ifComparisonBranch(failure, "!=", CLASS);
- tsmb.loadLocal(parameter);
- tsmb.checkCast(classBuilder.getType());
- LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
- tsmb.storeLocal(other);
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+ LocalVariable parameter = tsmb.getParameter(0);
+ Label success = tsmb.createLabel();
+ Label failure = tsmb.createLabel();
- // Compare fields
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- tsmb.loadLocal(other);
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- equals(tsmb, type, failure);
- }
+ // Check type
+ tsmb.loadThis();
+ tsmb.loadLocal(parameter);
+ tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
+ tsmb.loadLocal(parameter);
+ tsmb.ifNullBranch(failure, true);
+ tsmb.loadLocal(parameter);
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadThis();
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.ifComparisonBranch(failure, "!=", CLASS);
+ tsmb.loadLocal(parameter);
+ tsmb.checkCast(classBuilder.getType());
+ LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
+ tsmb.storeLocal(other);
- // Return
- tsmb.setLocation(success);
- tsmb.loadConstant(true);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.setLocation(failure);
- tsmb.loadConstant(false);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.finish();
+ // Compare fields
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ tsmb.loadLocal(other);
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ equals(tsmb, type, failure);
}
- // Create hashCode
- {
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadConstant(recordName.hashCode());
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadConstant(31);
- tsmb.math(Opcodes.IMUL);
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- hashCode(tsmb, type);
- tsmb.math(Opcodes.IADD);
- }
- tsmb.returnValue(TypeDesc.INT);
- tsmb.finish();
+ // Return
+ tsmb.setLocation(success);
+ tsmb.loadConstant(true);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.setLocation(failure);
+ tsmb.loadConstant(false);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.finish();
+ }
+
+ // Create hashCode
+ {
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadConstant(recordName.hashCode());
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadConstant(31);
+ tsmb.math(Opcodes.IMUL);
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ hashCode(tsmb, type);
+ tsmb.math(Opcodes.IADD);
}
+ tsmb.returnValue(TypeDesc.INT);
+ tsmb.finish();
}
}
// Create fields
CodeBuilderUtils.makeRecord(classBuilder, functionValue.toString(), Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "p",
Arrays.copyOf(parameterTypes, knownParametersCount),
- false);
+ true);
// Create apply
{
for(int i=0;i<knownParametersCount;++i) {
mb.loadThis();
mb.loadLocal(mb.getParameter(i));
- mb.storeField(className, "p"+i, parameterTypes[i]);
+ mb.storeField(className, "p"+i, parameterTypes[i]);
}
mb.returnVoid();
mb.finish();
functionValue.applyExact(mb, parameters);
mb.box(functionValue.getReturnType());
mb.returnValue(TypeDesc.OBJECT);
- }
+ }
+
+ CodeBuilderUtils.implementHashCodeAndEquals(classBuilder, functionValue.toString(), "p", parameterTypes);
}
// Finish
--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.utils;
+
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class SSAUtils {
+
+ public static boolean representSameValue(Val a, ValRef b) {
+ if(b.getTypeParameters().length > 0)
+ return false;
+ return representSameValue(a, b.getBinding());
+ }
+
+ public static boolean representSameValue(Val a, Val b) {
+ if(a == b)
+ return true;
+ Type aT = a.getType();
+ Type bT = b.getType();
+ if(!Types.equals(aT, bT))
+ return false;
+ return isSingletonType(aT);
+ }
+
+ public static boolean isSingletonType(Type type) {
+ type = Types.canonical(type);
+ return type == Types.UNIT || type == Types.PUNIT;
+ }
+
+}
public class ValueFromMethod {
+ private static final class Arity1Func extends FunctionImpl1<Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity1Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0) {
+ try {
+ Object ret = method.invoke(null, p0);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity1Func other = (Arity1Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity2Func extends FunctionImpl2<Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity2Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1) {
+ try {
+ Object ret = method.invoke(null, p0, p1);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity2Func other = (Arity2Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity3Func extends FunctionImpl3<Object, Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity3Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1, Object p2) {
+ try {
+ Object ret = method.invoke(null, p0, p1, p2);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity3Func other = (Arity3Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class Arity4Func extends FunctionImpl4<Object, Object, Object, Object, Object> {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private Arity4Func(Method method, boolean returnsVoid) {
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object apply(Object p0, Object p1, Object p2, Object p3) {
+ try {
+ Object ret = method.invoke(null, p0, p1, p2, p3);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Arity4Func other = (Arity4Func) obj;
+ return method.equals(other.method);
+ }
+ }
+
+ private static final class ArityNFunc extends FunctionImplN {
+ private final Method method;
+ private final boolean returnsVoid;
+
+ private ArityNFunc(int arity, Method method, boolean returnsVoid) {
+ super(arity);
+ this.method = method;
+ this.returnsVoid = returnsVoid;
+ }
+
+ @Override
+ public Object doApply(Object... ps) {
+ try {
+ Object ret = method.invoke(null, ps);
+ return returnsVoid ? Tuple0.INSTANCE : ret;
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method == null ? 0 : method.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ArityNFunc other = (ArityNFunc) obj;
+ return method.equals(other.method);
+ }
+ }
+
public static Object getValueFromStaticMethod(final Method method) throws ReflectiveOperationException {
int arity = method.getParameterTypes().length;
final boolean returnsVoid = method.getReturnType().equals(void.class);
return returnsVoid ? Tuple0.INSTANCE : ret;
}
case 1:
- return new FunctionImpl1<Object,Object>() {
- @Override
- public Object apply(Object p0) {
- try {
- Object ret = method.invoke(null, p0);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity1Func(method, returnsVoid);
case 2:
- return new FunctionImpl2<Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1) {
- try {
- Object ret = method.invoke(null, p0, p1);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity2Func(method, returnsVoid);
case 3:
- return new FunctionImpl3<Object,Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1, Object p2) {
- try {
- Object ret = method.invoke(null, p0, p1, p2);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity3Func(method, returnsVoid);
case 4:
- return new FunctionImpl4<Object,Object,Object,Object,Object>() {
- @Override
- public Object apply(Object p0, Object p1, Object p2, Object p3) {
- try {
- Object ret = method.invoke(null, p0, p1, p2, p3);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new Arity4Func(method, returnsVoid);
default:
- return new FunctionImplN(arity) {
- @Override
- public Object doApply(Object... ps) {
- try {
- Object ret = method.invoke(null, ps);
- return returnsVoid ? Tuple0.INSTANCE : ret;
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- };
+ return new ArityNFunc(arity, method, returnsVoid);
}
}
--- /dev/null
+package org.simantics.scl.compiler.internal.header;
+
+import org.simantics.scl.compiler.elaboration.expressions.annotations.AnnotationUtils;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
+import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader;
+
+public class ModuleHeader {
+ public String classLoader;
+ public long classLoaderLocation;
+
+ private void read(ErrorLog errorLog, DModuleHeader header) {
+ for(FieldAssignment assignment : header.fields)
+ switch(assignment.name) {
+ case "bundle":
+ if(assignment.value == null)
+ errorLog.log(assignment.location, "Property classLoader needs to be given a string value.");
+ else {
+ classLoader = AnnotationUtils.extractString(assignment.value);
+ if(classLoader == null)
+ errorLog.log(assignment.value.location, "Expected bundle name here.");
+ else
+ classLoaderLocation = assignment.location;
+ }
+ break;
+ default:
+ errorLog.logWarning(assignment.location, "Unknown module header field was skipped.");
+ }
+ }
+
+ public static ModuleHeader process(ErrorLog errorLog, DModuleHeader header) {
+ if(header == null)
+ return null;
+ ModuleHeader result = new ModuleHeader();
+ result.read(errorLog, header);
+ return result;
+ }
+}
package org.simantics.scl.compiler.internal.interpreted;
+import java.util.Arrays;
+
import org.simantics.scl.runtime.function.FunctionImpl1;
import org.simantics.scl.runtime.function.FunctionImpl2;
import org.simantics.scl.runtime.function.FunctionImpl3;
import org.simantics.scl.runtime.function.FunctionImplN;
public class ILambda implements IExpression {
+ private final class Arity1Func extends FunctionImpl1 {
+ private final Object[] inheritedVariableBindings;
+
+ private Arity1Func(Object[] inheritedVariableBindings) {
+ this.inheritedVariableBindings = inheritedVariableBindings;
+ }
+
+ @Override
+ public Object apply(Object param0) {
+ Object[] newVariableBindings = new Object[variableBindingsLength];
+ int i = 0;;
+ for(;i < inheritedVariableBindings.length;++i)
+ newVariableBindings[i] = inheritedVariableBindings[i];
+ newVariableBindings[i] = param0;
+ return body.execute(newVariableBindings);
+ }
+
+ @Override
+ public String toString() {
+ return ILambda.this.toString(inheritedVariableBindings);
+ }
+
+ @Override
+ public int hashCode() {
+ return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+ }
+
+ private ILambda getParent() {
+ return ILambda.this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ Arity1Func other = (Arity1Func)obj;
+ return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+ }
+ }
+
+ private final class Arity2Func extends FunctionImpl2 {
+ private final Object[] inheritedVariableBindings;
+
+ private Arity2Func(Object[] inheritedVariableBindings) {
+ this.inheritedVariableBindings = inheritedVariableBindings;
+ }
+
+ @Override
+ public Object apply(Object param0, Object param1) {
+ Object[] newVariableBindings = new Object[variableBindingsLength];
+ int i = 0;;
+ for(;i < inheritedVariableBindings.length;++i)
+ newVariableBindings[i] = inheritedVariableBindings[i];
+ newVariableBindings[i++] = param0;
+ newVariableBindings[i] = param1;
+ return body.execute(newVariableBindings);
+ }
+
+ @Override
+ public String toString() {
+ return ILambda.this.toString(inheritedVariableBindings);
+ }
+
+ @Override
+ public int hashCode() {
+ return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+ }
+
+ private ILambda getParent() {
+ return ILambda.this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ Arity2Func other = (Arity2Func)obj;
+ return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+ }
+ }
+
+ private final class Arity3Func extends FunctionImpl3 {
+ private final Object[] inheritedVariableBindings;
+
+ private Arity3Func(Object[] inheritedVariableBindings) {
+ this.inheritedVariableBindings = inheritedVariableBindings;
+ }
+
+ @Override
+ public Object apply(Object param0, Object param1, Object param2) {
+ Object[] newVariableBindings = new Object[variableBindingsLength];
+ int i = 0;;
+ for(;i < inheritedVariableBindings.length;++i)
+ newVariableBindings[i] = inheritedVariableBindings[i];
+ newVariableBindings[i++] = param0;
+ newVariableBindings[i++] = param1;
+ newVariableBindings[i] = param2;
+ return body.execute(newVariableBindings);
+ }
+
+ @Override
+ public String toString() {
+ return ILambda.this.toString(inheritedVariableBindings);
+ }
+
+ @Override
+ public int hashCode() {
+ return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+ }
+
+ private ILambda getParent() {
+ return ILambda.this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ Arity3Func other = (Arity3Func)obj;
+ return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+ }
+ }
+
+ private final class Arity4Func extends FunctionImpl4 {
+ private final Object[] inheritedVariableBindings;
+
+ private Arity4Func(Object[] inheritedVariableBindings) {
+ this.inheritedVariableBindings = inheritedVariableBindings;
+ }
+
+ @Override
+ public Object apply(Object param0, Object param1, Object param2, Object param3) {
+ Object[] newVariableBindings = new Object[variableBindingsLength];
+ int i = 0;;
+ for(;i < inheritedVariableBindings.length;++i)
+ newVariableBindings[i] = inheritedVariableBindings[i];
+ newVariableBindings[i++] = param0;
+ newVariableBindings[i++] = param1;
+ newVariableBindings[i++] = param2;
+ newVariableBindings[i] = param3;
+ return body.execute(newVariableBindings);
+ }
+
+ @Override
+ public String toString() {
+ return ILambda.this.toString(inheritedVariableBindings);
+ }
+
+ @Override
+ public int hashCode() {
+ return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+ }
+
+ private ILambda getParent() {
+ return ILambda.this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ Arity4Func other = (Arity4Func)obj;
+ return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+ }
+ }
+
+ private final class ArityNFunc extends FunctionImplN {
+ private final Object[] inheritedVariableBindings;
+
+ private ArityNFunc(Object[] inheritedVariableBindings) {
+ super(arity);
+ this.inheritedVariableBindings = inheritedVariableBindings;
+ }
+
+ @Override
+ public Object doApply(Object... ps) {
+ Object[] newVariableBindings = new Object[variableBindingsLength];
+ int i = 0;;
+ for(;i < inheritedVariableBindings.length;++i)
+ newVariableBindings[i] = inheritedVariableBindings[i];
+ for(Object p : ps)
+ newVariableBindings[i++] = p;
+ return body.execute(newVariableBindings);
+ }
+
+ @Override
+ public String toString() {
+ return ILambda.this.toString(inheritedVariableBindings);
+ }
+
+ @Override
+ public int hashCode() {
+ return ILambda.this.hashCode() + 31*Arrays.hashCode(inheritedVariableBindings);
+ }
+
+ private ILambda getParent() {
+ return ILambda.this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ ArityNFunc other = (ArityNFunc)obj;
+ return ILambda.this == other.getParent() && Arrays.equals(inheritedVariableBindings, other.inheritedVariableBindings);
+ }
+ }
+
private final int[] inheritedVariableIds;
private final int arity;
private final int variableBindingsLength;
private final IExpression body;
-
+
public ILambda(int[] inheritedVariableIds, int arity,
int variableBindingsLength, IExpression body) {
this.inheritedVariableIds = inheritedVariableIds;
this.body = body;
}
- @SuppressWarnings("rawtypes")
@Override
public Object execute(Object[] variableBindings) {
final Object[] inheritedVariableBindings = new Object[inheritedVariableIds.length];
inheritedVariableBindings[i] = variableBindings[inheritedVariableIds[i]];
switch(arity) {
case 1:
- return new FunctionImpl1() {
- @Override
- public Object apply(Object param0) {
- Object[] newVariableBindings = new Object[variableBindingsLength];
- int i = 0;;
- for(;i < inheritedVariableBindings.length;++i)
- newVariableBindings[i] = inheritedVariableBindings[i];
- newVariableBindings[i] = param0;
- return body.execute(newVariableBindings);
- }
-
- @Override
- public String toString() {
- return ILambda.this.toString(inheritedVariableBindings);
- }
- };
+ return new Arity1Func(inheritedVariableBindings);
case 2:
- return new FunctionImpl2() {
- @Override
- public Object apply(Object param0, Object param1) {
- Object[] newVariableBindings = new Object[variableBindingsLength];
- int i = 0;;
- for(;i < inheritedVariableBindings.length;++i)
- newVariableBindings[i] = inheritedVariableBindings[i];
- newVariableBindings[i++] = param0;
- newVariableBindings[i] = param1;
- return body.execute(newVariableBindings);
- }
-
- @Override
- public String toString() {
- return ILambda.this.toString(inheritedVariableBindings);
- }
- };
+ return new Arity2Func(inheritedVariableBindings);
case 3:
- return new FunctionImpl3() {
- @Override
- public Object apply(Object param0, Object param1, Object param2) {
- Object[] newVariableBindings = new Object[variableBindingsLength];
- int i = 0;;
- for(;i < inheritedVariableBindings.length;++i)
- newVariableBindings[i] = inheritedVariableBindings[i];
- newVariableBindings[i++] = param0;
- newVariableBindings[i++] = param1;
- newVariableBindings[i] = param2;
- return body.execute(newVariableBindings);
- }
-
- @Override
- public String toString() {
- return ILambda.this.toString(inheritedVariableBindings);
- }
- };
+ return new Arity3Func(inheritedVariableBindings);
case 4:
- return new FunctionImpl4() {
- @Override
- public Object apply(Object param0, Object param1, Object param2, Object param3) {
- Object[] newVariableBindings = new Object[variableBindingsLength];
- int i = 0;;
- for(;i < inheritedVariableBindings.length;++i)
- newVariableBindings[i] = inheritedVariableBindings[i];
- newVariableBindings[i++] = param0;
- newVariableBindings[i++] = param1;
- newVariableBindings[i++] = param2;
- newVariableBindings[i] = param3;
- return body.execute(newVariableBindings);
- }
-
- @Override
- public String toString() {
- return ILambda.this.toString(inheritedVariableBindings);
- }
- };
+ return new Arity4Func(inheritedVariableBindings);
default:
- return new FunctionImplN(arity) {
- @Override
- public Object doApply(Object... ps) {
- Object[] newVariableBindings = new Object[variableBindingsLength];
- int i = 0;;
- for(;i < inheritedVariableBindings.length;++i)
- newVariableBindings[i] = inheritedVariableBindings[i];
- for(Object p : ps)
- newVariableBindings[i++] = p;
- return body.execute(newVariableBindings);
- }
-
- @Override
- public String toString() {
- return ILambda.this.toString(inheritedVariableBindings);
- }
- };
+ return new ArityNFunc(inheritedVariableBindings);
}
}
-
+
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append(')');
return b.toString();
}
-
+
public String toString(Object[] variableBindings) {
- StringBuilder sb = new StringBuilder();
- appendVariableBindings(sb, variableBindings);
- sb.append(this.toString());
- return sb.toString();
+ StringBuilder sb = new StringBuilder();
+ appendVariableBindings(sb, variableBindings);
+ sb.append(this.toString());
+ return sb.toString();
}
-
+
private static void appendVariableBindings(StringBuilder sb, Object[] variableBindings) {
- if (variableBindings.length > 0) {
- sb.append("(let {");
- for(int i = 0; i < variableBindings.length; i++) {
- if (i > 0) sb.append("; ");
- sb.append("v").append(i).append("=").append(variableBindings[i].toString());
- }
- sb.append("} in ");
- }
+ if (variableBindings.length > 0) {
+ sb.append("(let {");
+ for(int i = 0; i < variableBindings.length; i++) {
+ if (i > 0) sb.append("; ");
+ sb.append("v").append(i).append("=").append(variableBindings[i].toString());
+ }
+ sb.append("} in ");
+ }
}
}
--- /dev/null
+package org.simantics.scl.compiler.internal.parsing.declarations;
+
+import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
+
+
+
+public class DModuleHeader extends DeclarationAst {
+ public final FieldAssignment[] fields;
+
+ public DModuleHeader(FieldAssignment[] fields) {
+ this.fields = fields;
+ }
+
+ @Override
+ public void toString(int indentation, StringBuilder b) {
+ for(int i=0;i<indentation;++i) b.append(" ");
+ b.append("module {");
+ ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
+ boolean first = true;
+ for(FieldAssignment field : fields) {
+ if(first)
+ first = false;
+ else
+ b.append(',');
+ b.append('\n');
+ for(int i=0;i<=indentation;++i) b.append(" ");
+ b.append(field.name);
+ b.append(" = ");
+ field.value.accept(visitor);
+ }
+ b.append('\n');
+ for(int i=0;i<indentation;++i) b.append(" ");
+ b.append('}');
+ }
+}
;
declaration
- = var (COMMA var)* HASTYPE type # TypeAnnotation
+ = MODULE LBRACE (field (COMMA field)*)? RBRACE # ModuleHeader
+ | var (COMMA var)* HASTYPE type # TypeAnnotation
| bexp rhs # ValueDefinition
| DATA ID+ (EQUALS constructor (BAR constructor)*)? # DataDefinition
| TYPE ID+ EQUALS type # TypeDefinition
public static final boolean TRACE = false;
private static final int INITIAL_CAPACITY = 16;
- private static final int STATE_COUNT = 344;
- private static final int TERMINAL_COUNT = 82;
+ private static final int STATE_COUNT = 349;
+ private static final int TERMINAL_COUNT = 83;
private static final int NONTERMINAL_COUNT = 51;
- private static final int PRODUCT_COUNT = 132;
+ private static final int PRODUCT_COUNT = 133;
private static final int[] ACTION_ROW_ID = new int[STATE_COUNT];
private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT];
- private static final short[] ACTION_TABLE = new short[6120];
- private static final int[] ERROR_TABLE = new int[882];
+ private static final short[] ACTION_TABLE = new short[6396];
+ private static final int[] ERROR_TABLE = new int[906];
private static final int[] GOTO_ROW_ID = new int[STATE_COUNT];
private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT];
- private static final short[] GOTO_TABLE = new short[1829];
+ private static final short[] GOTO_TABLE = new short[1652];
private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT];
private static final short STATE_MASK = (short)0x0fff;
"SEMICOLON",
"LBRACE",
"RBRACE",
+ "MODULE",
"COMMA",
"HASTYPE",
"DATA",
"command",
"statement",
"declarations",
+ "field",
"var",
"bexp",
"rhs",
"stringLiteral",
"symbolWithoutMinus",
"listQualifier",
- "field",
"chrQuery",
"verboseChrQuery",
"caseRhs",
return parse(0);
}
public Object parseCommands() {
- return parse(329);
+ return parse(334);
}
public Object parseImport() {
- return parse(336);
+ return parse(341);
}
public Object parseType() {
- return parse(338);
+ return parse(343);
}
public Object parseExp() {
- return parse(340);
+ return parse(345);
}
public Object parseEquationBlock() {
- return parse(342);
+ return parse(347);
}
case 7:
return reduceEquationBlock();
case 8:
- return reduceTypeAnnotation();
+ return reduceModuleHeader();
case 9:
- return reduceValueDefinition();
+ return reduceTypeAnnotation();
case 10:
- return reduceDataDefinition();
+ return reduceValueDefinition();
case 11:
- return reduceTypeDefinition();
+ return reduceDataDefinition();
case 12:
- return reduceClassDefinition();
+ return reduceTypeDefinition();
case 13:
- return reduceInstanceDefinition();
+ return reduceClassDefinition();
case 14:
- return reduceDerivingInstanceDefinition();
+ return reduceInstanceDefinition();
case 15:
- return reduceDocumentationString();
+ return reduceDerivingInstanceDefinition();
case 16:
- return reduceAnnotation();
+ return reduceDocumentationString();
case 17:
- return reducePrecedenceDefinition();
+ return reduceAnnotation();
case 18:
- return reduceJustImport();
+ return reducePrecedenceDefinition();
case 19:
- return reduceImportJava();
+ return reduceJustImport();
case 20:
- return reduceEffectDefinition();
+ return reduceImportJava();
case 21:
- return reduceRuleDefinition();
+ return reduceEffectDefinition();
case 22:
- return reduceMappingRelationDefinition();
+ return reduceRuleDefinition();
case 23:
- return reduceRelationDefinition();
+ return reduceMappingRelationDefinition();
case 24:
- return reduceStatementCommand();
+ return reduceRelationDefinition();
case 25:
- return reduceImportCommand();
+ return reduceStatementCommand();
case 26:
- return reduceGuardStatement();
+ return reduceImportCommand();
case 27:
- return reduceLetStatement();
+ return reduceGuardStatement();
case 28:
- return reduceBindStatement();
+ return reduceLetStatement();
case 29:
- return reduceRuleStatement();
+ return reduceBindStatement();
case 30:
- return reduceCHRStatement();
+ return reduceRuleStatement();
case 31:
- return reduceVerboseCHRStatement();
+ return reduceCHRStatement();
case 32:
- return reduceConstraintStatement();
+ return reduceVerboseCHRStatement();
case 33:
- return reduceDeclarations();
+ return reduceConstraintStatement();
case 34:
- return reduceVarId();
+ return reduceDeclarations();
case 35:
- return reduceEscapedSymbol();
+ return reduceField();
case 36:
- return reduceTupleConstructor();
+ return reduceFieldShorthand();
case 37:
- return reduceBinary();
+ return reduceVarId();
case 38:
- return reduceSimpleRhs();
+ return reduceEscapedSymbol();
case 39:
- return reduceGuardedRhs();
+ return reduceTupleConstructor();
case 40:
- return reduceConstructor();
+ return reduceBinary();
case 41:
- return reduceRecordConstructor();
+ return reduceSimpleRhs();
case 42:
- return reduceContext();
+ return reduceGuardedRhs();
case 43:
- return reduceFundeps();
+ return reduceConstructor();
case 44:
- return reduceTypeVar();
+ return reduceRecordConstructor();
case 45:
- return reduceTupleType();
+ return reduceContext();
case 46:
- return reduceListType();
+ return reduceFundeps();
case 47:
- return reduceListTypeConstructor();
+ return reduceTypeVar();
case 48:
- return reduceTupleTypeConstructor();
+ return reduceTupleType();
case 49:
- return reduceLambda();
+ return reduceListType();
case 50:
- return reduceLambdaMatch();
+ return reduceListTypeConstructor();
case 51:
- return reduceLet();
+ return reduceTupleTypeConstructor();
case 52:
- return reduceIf();
+ return reduceLambda();
case 53:
- return reduceMatch();
+ return reduceLambdaMatch();
case 54:
- return reduceDo();
+ return reduceLet();
case 55:
- return reduceSelect();
+ return reduceIf();
case 56:
- return reduceEnforce();
+ return reduceMatch();
case 57:
- return reduceVar();
+ return reduceDo();
case 58:
- return reduceHashedId();
+ return reduceSelect();
case 59:
- return reduceBlank();
+ return reduceEnforce();
case 60:
- return reduceInteger();
+ return reduceVar();
case 61:
- return reduceFloat();
+ return reduceHashedId();
case 62:
- return reduceString();
+ return reduceBlank();
case 63:
- return reduceChar();
+ return reduceInteger();
case 64:
- return reduceTuple();
+ return reduceFloat();
case 65:
- return reduceViewPattern();
+ return reduceString();
case 66:
- return reduceRightSection();
+ return reduceChar();
case 67:
- return reduceLeftSection();
+ return reduceTuple();
case 68:
- return reduceListLiteral();
+ return reduceViewPattern();
case 69:
- return reduceRange();
+ return reduceRightSection();
case 70:
- return reduceListComprehension();
+ return reduceLeftSection();
case 71:
- return reduceAs();
+ return reduceListLiteral();
case 72:
- return reduceRecord();
+ return reduceRange();
case 73:
- return reduceTransformation();
+ return reduceListComprehension();
case 74:
- return reduceEq();
+ return reduceAs();
case 75:
- return reduceRuleDeclarations();
+ return reduceRecord();
case 76:
- return reduceImportShowing();
+ return reduceTransformation();
case 77:
- return reduceImportHiding();
+ return reduceEq();
case 78:
- return reduceImportValueItem();
+ return reduceRuleDeclarations();
case 79:
- return reduceFieldDescription();
+ return reduceImportShowing();
case 80:
- return reduceStatements();
+ return reduceImportHiding();
case 81:
- return reduceGuardedExpEq();
+ return reduceImportValueItem();
case 82:
- return reduceFundep();
+ return reduceFieldDescription();
case 83:
- return reduceQueryRuleDeclaration();
+ return reduceStatements();
case 84:
- return reduceAnnotation();
+ return reduceGuardedExpEq();
case 85:
- return reduceGuardQuery();
+ return reduceFundep();
case 86:
- return reduceEqualsQuery();
+ return reduceQueryRuleDeclaration();
case 87:
- return reduceBindQuery();
+ return reduceAnnotation();
case 88:
- return reduceCompositeQuery();
+ return reduceGuardQuery();
case 89:
- return reduceQueryBlock();
+ return reduceEqualsQuery();
case 90:
- return reduceApply();
+ return reduceBindQuery();
case 91:
- return reduceSymbol();
+ return reduceCompositeQuery();
case 92:
- return reduceEscapedId();
+ return reduceQueryBlock();
case 93:
- return reduceMinus();
+ return reduceApply();
case 94:
- return reduceLess();
+ return reduceSymbol();
case 95:
- return reduceGreater();
+ return reduceEscapedId();
case 96:
- return reduceDot();
+ return reduceMinus();
case 97:
- return reduceFieldAccess();
+ return reduceLess();
case 98:
- return reduceIdAccessor();
+ return reduceGreater();
case 99:
- return reduceStringAccessor();
+ return reduceDot();
case 100:
- return reduceExpAccessor();
+ return reduceFieldAccess();
case 101:
- return reduceCase();
+ return reduceIdAccessor();
case 102:
- return reduceStringLiteral();
+ return reduceStringAccessor();
case 103:
- return reduceSymbol();
+ return reduceExpAccessor();
case 104:
- return reduceEscapedId();
+ return reduceCase();
case 105:
- return reduceLess();
+ return reduceStringLiteral();
case 106:
- return reduceGreater();
+ return reduceSymbol();
case 107:
- return reduceDot();
+ return reduceEscapedId();
case 108:
- return reduceGuardQualifier();
+ return reduceLess();
case 109:
- return reduceLetQualifier();
+ return reduceGreater();
case 110:
- return reduceBindQualifier();
+ return reduceDot();
case 111:
- return reduceThenQualifier();
+ return reduceGuardQualifier();
case 112:
- return reduceField();
+ return reduceLetQualifier();
case 113:
- return reduceFieldShorthand();
+ return reduceBindQualifier();
case 114:
- return reduceCHRQuery();
+ return reduceThenQualifier();
case 115:
- return reduceVerboseCHRQuery();
+ return reduceCHRQuery();
case 116:
- return reduceSimpleCaseRhs();
+ return reduceVerboseCHRQuery();
case 117:
- return reduceGuardedCaseRhs();
+ return reduceSimpleCaseRhs();
case 118:
- return reduceGuardedExpArrow();
+ return reduceGuardedCaseRhs();
case 119:
- return reduceGuardEquation();
+ return reduceGuardedExpArrow();
case 120:
- return reduceBasicEquation();
+ return reduceGuardEquation();
case 121:
- return reduceEffect();
+ return reduceBasicEquation();
case 122:
- return reduceJustEtype();
+ return reduceEffect();
case 123:
- return reduceForAll();
+ return reduceJustEtype();
case 124:
- return reduceApplyType();
+ return reduceForAll();
case 125:
+ return reduceApplyType();
+ case 126:
return reduceDummy();
default:
* equationBlock ::= (equation (SEMICOLON equation)*)?
*/
protected abstract Object reduceEquationBlock();
+ /**
+ * declaration ::= MODULE LBRACE (field (COMMA field)*)? RBRACE
+ */
+ protected abstract Object reduceModuleHeader();
/**
* declaration ::= (var COMMA)* var HASTYPE type
*/
* declarations ::= LBRACE (declaration (SEMICOLON (declaration SEMICOLON)* declaration)?)? RBRACE
*/
protected abstract Object reduceDeclarations();
+ /**
+ * field ::= ID EQUALS exp
+ */
+ protected abstract Object reduceField();
+ /**
+ * field ::= ID
+ */
+ protected abstract Object reduceFieldShorthand();
/**
* var ::= ID
*/
* listQualifier ::= THEN exp (BY exp)?
*/
protected abstract Object reduceThenQualifier();
- /**
- * field ::= ID EQUALS exp
- */
- protected abstract Object reduceField();
- /**
- * field ::= ID
- */
- protected abstract Object reduceFieldShorthand();
/**
* chrQuery ::= (listQualifier COMMA)* listQualifier
*/
import org.simantics.scl.compiler.internal.parsing.declarations.DImportJavaAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DInstanceAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DMappingRelationAst;
+import org.simantics.scl.compiler.internal.parsing.declarations.DModuleHeader;
import org.simantics.scl.compiler.internal.parsing.declarations.DRelationAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DRuleAst;
import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
@Override
protected Object reduceModule() {
ArrayList<DeclarationAst> declarations = new ArrayList<DeclarationAst>(length()/2+1);
- for(int i=0;i<length();i+=2)
- declarations.add((DeclarationAst)get(i));
+ for(int i=0;i<length();i+=2) {
+ DeclarationAst declaration = (DeclarationAst)get(i);
+ if(declaration == null)
+ throw new NullPointerException();
+ declarations.add(declaration);
+ }
return declarations;
}
+
+ @Override
+ protected Object reduceModuleHeader() {
+ FieldAssignment[] fields = new FieldAssignment[length()/2-1];
+ for(int i=0;i<fields.length;++i)
+ fields[i] = (FieldAssignment)get(2+i*2);
+ return new DModuleHeader(fields);
+ }
@Override
protected Object reduceLocalTypeAnnotation() {
public class SCLParserOptions {
public static final SCLParserOptions DEFAULT = new SCLParserOptions();
+ public static final SCLParserOptions MODULE_DEFAULT = new SCLParserOptions();
+
+ static {
+ MODULE_DEFAULT.isModule = true;
+ }
public boolean supportEq;
+ public boolean isModule;
}
int lineStart = 0;
boolean firstTokenOfLine = true;
private SCLParserOptions options;
+ private boolean isFirstToken = true;
{
indentations.add(0);
}
}
firstTokenOfLine = false;
+ if(isFirstToken) {
+ isFirstToken = false;
+ if(symbol.id == SCLTerminals.ID && symbol.text.equals("module") && options != null && options.isModule) {
+ push(new Token(SCLTerminals.MODULE, symbol.location, symbol.text));
+ return;
+ }
+ }
}
switch(symbolId) {
return;
case SCLTerminals.THEN:
/*for(int tt : indentationTokens.toArray())
- System.out.print(SCLParser.TERMINAL_NAMES[tt] + " ");
- System.out.println();*/
+ System.out.print(SCLParser.TERMINAL_NAMES[tt] + " ");
+ System.out.println();*/
if(prevTokenId == SCLTerminals.COMMA) {
// for list comprehension syntax
push(symbol);
public static final int SEMICOLON = 0;
public static final int LBRACE = 1;
public static final int RBRACE = 2;
- public static final int COMMA = 3;
- public static final int HASTYPE = 4;
- public static final int DATA = 5;
- public static final int ID = 6;
- public static final int EQUALS = 7;
- public static final int BAR = 8;
- public static final int TYPE = 9;
- public static final int CLASS = 10;
- public static final int WHERE = 11;
- public static final int INSTANCE = 12;
- public static final int DERIVING = 13;
- public static final int BEGIN_STRING = 14;
- public static final int END_STRING = 15;
- public static final int ANNOTATION_ID = 16;
- public static final int INFIX = 17;
- public static final int INFIXL = 18;
- public static final int INFIXR = 19;
- public static final int INTEGER = 20;
- public static final int IMPORTJAVA = 21;
- public static final int EFFECT = 22;
- public static final int RULE = 23;
- public static final int ABSTRACT_RULE = 24;
- public static final int EXTENDS = 25;
- public static final int MAPPING_RELATION = 26;
- public static final int FOLLOWS = 27;
- public static final int IMPORT = 28;
- public static final int INCLUDE = 29;
- public static final int AS = 30;
- public static final int LPAREN = 31;
- public static final int RPAREN = 32;
- public static final int HIDING = 33;
- public static final int ARROW = 34;
- public static final int COLON = 35;
- public static final int WITH = 36;
- public static final int MINUS = 37;
- public static final int SYMBOL = 38;
- public static final int LESS = 39;
- public static final int GREATER = 40;
- public static final int SEPARATED_DOT = 41;
- public static final int ESCAPED_ID = 42;
- public static final int LAMBDA = 43;
- public static final int LAMBDA_MATCH = 44;
- public static final int LET = 45;
- public static final int IF = 46;
- public static final int MATCH = 47;
- public static final int DO = 48;
- public static final int MDO = 49;
- public static final int ENFORCE = 50;
- public static final int BLANK = 51;
- public static final int FLOAT = 52;
- public static final int LBRACKET = 53;
- public static final int ESCAPED_SYMBOL = 54;
- public static final int CHAR = 55;
- public static final int WHEN = 56;
- public static final int ATTACHED_HASH = 57;
- public static final int SELECT = 58;
- public static final int SELECT_FIRST = 59;
- public static final int SELECT_DISTINCT = 60;
- public static final int TRANSFORMATION = 61;
- public static final int EQ = 62;
- public static final int ATTACHED_DOT = 63;
- public static final int IN = 64;
- public static final int THEN = 65;
- public static final int ELSE = 66;
- public static final int RBRACKET = 67;
- public static final int DOTDOT = 68;
- public static final int AT = 69;
- public static final int SUSPEND_STRING = 70;
- public static final int CONTINUE_STRING = 71;
- public static final int BINDS = 72;
- public static final int IMPLIES = 73;
- public static final int THEN_AFTER_WHEN = 74;
- public static final int CONSTRAINT = 75;
- public static final int BY = 76;
- public static final int QUERY_OP = 77;
- public static final int FORALL = 78;
- public static final int COMMENT = 79;
- public static final int EOL = 80;
- public static final int EOF = 81;
+ public static final int MODULE = 3;
+ public static final int COMMA = 4;
+ public static final int HASTYPE = 5;
+ public static final int DATA = 6;
+ public static final int ID = 7;
+ public static final int EQUALS = 8;
+ public static final int BAR = 9;
+ public static final int TYPE = 10;
+ public static final int CLASS = 11;
+ public static final int WHERE = 12;
+ public static final int INSTANCE = 13;
+ public static final int DERIVING = 14;
+ public static final int BEGIN_STRING = 15;
+ public static final int END_STRING = 16;
+ public static final int ANNOTATION_ID = 17;
+ public static final int INFIX = 18;
+ public static final int INFIXL = 19;
+ public static final int INFIXR = 20;
+ public static final int INTEGER = 21;
+ public static final int IMPORTJAVA = 22;
+ public static final int EFFECT = 23;
+ public static final int RULE = 24;
+ public static final int ABSTRACT_RULE = 25;
+ public static final int EXTENDS = 26;
+ public static final int MAPPING_RELATION = 27;
+ public static final int FOLLOWS = 28;
+ public static final int IMPORT = 29;
+ public static final int INCLUDE = 30;
+ public static final int AS = 31;
+ public static final int LPAREN = 32;
+ public static final int RPAREN = 33;
+ public static final int HIDING = 34;
+ public static final int ARROW = 35;
+ public static final int COLON = 36;
+ public static final int WITH = 37;
+ public static final int MINUS = 38;
+ public static final int SYMBOL = 39;
+ public static final int LESS = 40;
+ public static final int GREATER = 41;
+ public static final int SEPARATED_DOT = 42;
+ public static final int ESCAPED_ID = 43;
+ public static final int LAMBDA = 44;
+ public static final int LAMBDA_MATCH = 45;
+ public static final int LET = 46;
+ public static final int IF = 47;
+ public static final int MATCH = 48;
+ public static final int DO = 49;
+ public static final int MDO = 50;
+ public static final int ENFORCE = 51;
+ public static final int BLANK = 52;
+ public static final int FLOAT = 53;
+ public static final int LBRACKET = 54;
+ public static final int ESCAPED_SYMBOL = 55;
+ public static final int CHAR = 56;
+ public static final int WHEN = 57;
+ public static final int ATTACHED_HASH = 58;
+ public static final int SELECT = 59;
+ public static final int SELECT_FIRST = 60;
+ public static final int SELECT_DISTINCT = 61;
+ public static final int TRANSFORMATION = 62;
+ public static final int EQ = 63;
+ public static final int ATTACHED_DOT = 64;
+ public static final int IN = 65;
+ public static final int THEN = 66;
+ public static final int ELSE = 67;
+ public static final int RBRACKET = 68;
+ public static final int DOTDOT = 69;
+ public static final int AT = 70;
+ public static final int SUSPEND_STRING = 71;
+ public static final int CONTINUE_STRING = 72;
+ public static final int BINDS = 73;
+ public static final int IMPLIES = 74;
+ public static final int THEN_AFTER_WHEN = 75;
+ public static final int CONSTRAINT = 76;
+ public static final int BY = 77;
+ public static final int QUERY_OP = 78;
+ public static final int FORALL = 79;
+ public static final int COMMENT = 80;
+ public static final int EOL = 81;
+ public static final int EOF = 82;
}
CompilationError[] warnings = CompilationError.EMPTY_ARRAY;
Map<String, byte[]> classes = Collections.emptyMap();
+ ClassLoader parentClassLoader;
ModuleInitializer moduleInitializer;
protected Documentation documentation;
public CompilationError[] getWarnings() {
return warnings;
}
+
+ @Override
+ public ClassLoader getParentClassLoader() {
+ return parentClassLoader;
+ }
+
+ public void setParentClassLoader(ClassLoader parentClassLoader) {
+ if(parentClassLoader == null)
+ throw new NullPointerException();
+ this.parentClassLoader = parentClassLoader;
+ }
}
--- /dev/null
+package org.simantics.scl.compiler.module;
+
+public class InvalidModulePathException extends Exception {
+
+ private static final long serialVersionUID = 4981982587509793105L;
+
+ public InvalidModulePathException(String message) {
+ super(message);
+ }
+
+}
\ No newline at end of file
void dispose();
CompilationError[] getWarnings();
-
+ ClassLoader getParentClassLoader();
}
--- /dev/null
+package org.simantics.scl.compiler.module;
+
+public class ModuleUtils {
+ public static String resolveAbsolutePath(String moduleName, String relativeModuleName) throws InvalidModulePathException {
+ if (relativeModuleName.startsWith(".")) {
+ String originalRelativeModuleName = relativeModuleName;
+ int p = moduleName.lastIndexOf('/');
+ String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
+ while(relativeModuleName.startsWith(".")) {
+ if(relativeModuleName.startsWith("./")) {
+ relativeModuleName = relativeModuleName.substring(2);
+ }
+ else if(relativeModuleName.startsWith("../")) {
+ relativeModuleName = relativeModuleName.substring(3);
+ if(parentPackage.isEmpty()) {
+ throw new InvalidModulePathException("Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
+ }
+ p = parentPackage.lastIndexOf('/');
+ parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
+ }
+ else {
+ throw new InvalidModulePathException("Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
+ }
+ }
+ return parentPackage + "/" + relativeModuleName;
+ } else {
+ return relativeModuleName;
+ }
+ }
+}
if(parentModule != null)
parentModules.add(parentModule);
}*/
- RuntimeModule rm = new RuntimeModule(module, parentModules, source.getClassLoader());
+ RuntimeModule rm = new RuntimeModule(module, parentModules, module.getParentClassLoader());
ModuleInitializer initializer = module.getModuleInitializer();
if(initializer != null)
try {
public RuntimeModule(Module module, RuntimeModuleMap parentModuleMap,
ClassLoader parentClassLoader) {
+ if(parentClassLoader == null)
+ throw new NullPointerException();
this.module = module;
this.parentModuleMap = parentModuleMap;
this.classLoader = new ModuleClassLoader(parentClassLoader);
import org.simantics.scl.compiler.errors.Failure;
import org.simantics.scl.compiler.errors.Success;
import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.Module;
@SuppressWarnings("unchecked")
@Override
public Failable<Module> compileModule(final ModuleRepository environment, final UpdateListener listener, ModuleCompilationOptions options) {
- SCLCompiler compiler = new SCLCompiler(options);
+ SCLCompiler compiler = new SCLCompiler(options, getJavaReferenceValidatorFactory());
try {
compiler.addSource(getSourceReader(listener));
compiler.compile(
environment,
getBuiltinImports(listener),
listener),
- moduleName,
- getJavaReferenceValidator());
+ moduleName);
if(compiler.getErrorLog().hasNoErrors())
return new Success<Module>(compiler.getModule());
else {
}
}
+ public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
+ return new JavaReferenceValidatorFactory() {
+
+ @Override
+ public JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(String context) {
+ return (JavaReferenceValidator<Object, Object, Object, Object>)TextualModuleSource.this.getJavaReferenceValidator();
+ }
+
+ @Override
+ public JavaReferenceValidator<Object, Object, Object, Object> getDefaultJavaReferenceValidator() {
+ return (JavaReferenceValidator<Object, Object, Object, Object>)TextualModuleSource.this.getJavaReferenceValidator();
+ }
+ };
+ }
+
@Override
public double getPriority() {
return priority;
import org.osgi.service.component.annotations.Component;
import org.simantics.scl.compiler.elaboration.java.Builtins;
import org.simantics.scl.compiler.elaboration.java.JavaModule;
+import org.simantics.scl.compiler.elaboration.java.LoggingModule;
import org.simantics.scl.compiler.elaboration.java.MinigraphModule;
@Component
public BuiltinModuleSourceRepository() {
super(Builtins.INSTANCE,
JavaModule.INSTANCE,
- MinigraphModule.INSTANCE);
+ MinigraphModule.INSTANCE,
+ new LoggingModule());
}
}
importJava "org.simantics.db.common.utils.ListUtils" where
@JavaName toList
elementsOfList :: Resource -> <ReadGraph> [Resource]
+
+ @JavaName create
+ createList :: [Resource] -> <WriteGraph> Resource
+
+ @javaName insertBack
+ insertBack :: Resource -> [Resource] -> <WriteGraph> ()
+
+ @javaName removeElement
+ removeElement :: Resource -> Resource -> <WriteGraph> Boolean
+
+ @javaName swapWithPrevious
+ swapWithPrevious :: Resource -> Resource -> <WriteGraph> Boolean
+
+ @javaName swapWithNext
+ swapWithNext :: Resource -> Resource -> <WriteGraph> Boolean
+
importJava "org.simantics.db.common.utils.CommonDBUtils" where
isParent :: Resource -> Resource -> <ReadGraph> Boolean
unaryQuery :: (a -> <ReadGraph,e> b) -> a -> <ReadGraph> b
unaryQueryCached :: (a -> <ReadGraph,e> b) -> a -> <ReadGraph> b
+ "Makes a new read request with given procedure for calculating the result. The request is cached only if the current request is listened."
+ subquery :: (<ReadGraph,Proc> a) -> <ReadGraph,Proc> a
+ "Makes a new read request with given procedure for calculating the result. The request is always cached."
+ subqueryC :: (<ReadGraph,Proc> a) -> <ReadGraph,Proc> a
+
importJava "org.simantics.db.layer0.util.Layer0Utils" where
undo :: () -> <Proc> String
undoOperations :: Integer -> <Proc> String
sortByCluster :: [a] -> (a->Resource) -> <ReadGraph> [a]
makeSynchronous :: Boolean -> <ReadGraph> ()
listOntologies :: () -> <ReadGraph> [Resource]
+ emptyTrashBin :: () -> <Proc> ()
+ purgeDatabase :: () -> <Proc> ()
@private
@JavaName copyTo
"""
modelVariableOfVariable :: Variable -> <ReadGraph> Variable
-modelVariableOfVariable var = variable $ uriOf $ toResource $ modelOfVariable var
+modelVariableOfVariable var = variable $ uriOf $ modelOfVariable var
uniqueChild :: Model -> Resource -> String -> <ReadGraph> Variable
uniqueChild model typet childName = do
typeName = DB.nameOf typet
query = "Types: " + typeName + " AND Name: " + childName
- moduleResources = searchByQuery (toResource model) query
+ moduleResources = searchByQuery model query
variable $ uriOf $ moduleResources ! 0
"""
return graph.syncRequest(new SCLUnaryRead(fn, value), TransientCacheAsyncListener.<Object>instance());
}
+
+ private static class Subquery implements Read<Object> {
+ Function q;
+
+ public Subquery(Function q) {
+ this.q = q;
+ }
+
+ @Override
+ public Object perform(ReadGraph graph) throws DatabaseException {
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.put("graph", graph);
+ try {
+ return q.apply(Tuple0.INSTANCE);
+ } catch (Throwable e) {
+ if(e instanceof DatabaseException)
+ throw (DatabaseException)e;
+ else
+ throw new DatabaseException(e);
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return q.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(this == obj)
+ return true;
+ if(obj == null || obj.getClass() != getClass())
+ return false;
+ Subquery other = (Subquery)obj;
+ return q.equals(other.q);
+ }
+ }
+
+ public static Object subquery(ReadGraph graph, Function q) throws DatabaseException {
+ return graph.syncRequest(new Subquery(q));
+ }
+
+ public static Object subqueryC(ReadGraph graph, Function q) throws DatabaseException {
+ return graph.syncRequest(new Subquery(q), TransientCacheAsyncListener.<Object>instance());
+ }
}
import org.eclipse.core.runtime.FileLocator;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.EncodedTextualModuleSource;
}
}
+ public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
+ return new OsgiJavaReferenceValidatorFactory(bundle);
+ }
}
--- /dev/null
+package org.simantics.scl.osgi.internal;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleWiring;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
+import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator;
+import org.simantics.scl.compiler.types.Type;
+
+public class OsgiJavaReferenceValidatorFactory implements JavaReferenceValidatorFactory {
+
+ private final Bundle bundle;
+
+ public OsgiJavaReferenceValidatorFactory(Bundle bundle) {
+ this.bundle = bundle;
+ }
+
+ private static ClassLoader getClassLoader(Bundle bundle) {
+ if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
+ return Type.class.getClassLoader();
+ else {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if(wiring != null)
+ return wiring.getClassLoader();
+ throw new InternalCompilerError("Cannot get the class loader for bundle " + bundle.getSymbolicName() + ".");
+ }
+ }
+
+ private static JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(Bundle bundle) {
+ if(bundle == null)
+ return null;
+ return (JavaReferenceValidator<Object, Object, Object, Object>)
+ (JavaReferenceValidator<?, ?, ?, ?>)new RuntimeJavaReferenceValidator(getClassLoader(bundle));
+ }
+
+ private static Bundle getBundle(BundleContext bundleContext, String symbolicName) {
+ Bundle result = null;
+ for (Bundle candidate : bundleContext.getBundles())
+ if (candidate.getSymbolicName().equals(symbolicName))
+ if (result == null || result.getVersion().compareTo(candidate.getVersion()) < 0)
+ result = candidate;
+ return result;
+ }
+
+ @Override
+ public JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(String bundleName) {
+ System.out.println("getJavaReferenceValidator(" + bundleName + ")");
+ return getJavaReferenceValidator(getBundle(bundle.getBundleContext(), bundleName));
+ }
+
+ @Override
+ public JavaReferenceValidator<Object, Object, Object, Object> getDefaultJavaReferenceValidator() {
+ return getJavaReferenceValidator(bundle);
+ }
+
+}
public static final int MAX_ARITY = 8;
public static final String HEADER =
- "/**\n"
- + " * This code is generated in " + GenerateFunctions.class.getName() + ".\n"
- + " * Do not edit manually!\n"
+ "/**\r\n"
+ + " * This code is generated in " + GenerateFunctions.class.getName() + ".\r\n"
+ + " * Do not edit manually!\r\n"
+ " */"
;
p.println(" nps[i + " + n + "] = ps[i];");
p.println(" return f.applyArray(nps);");
p.println(" }");
+ p.println();
}
{
p.println(" @Override");
p.println(" sb.append(\")\");");
p.println(" return sb.toString();");
p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public int hashCode() {");
+ p.println(" int result = f.hashCode();");
+ for(int i=0;i<n;++i)
+ p.println(" result = 31 * result + (p"+i+" == null ? 0 : p"+i+".hashCode());");
+ p.println(" return result;");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public boolean equals(Object obj) {");
+ p.println(" if (this == obj)");
+ p.println(" return true;");
+ p.println(" if (obj == null)");
+ p.println(" return false;");
+ p.println(" if (getClass() != obj.getClass())");
+ p.println(" return false;");
+ p.println(" UnsaturatedFunction"+n+" other = (UnsaturatedFunction"+n+") obj;");
+ p.println(" if(!f.equals(other.f))");
+ p.println(" return false;");
+ for(int i=0;i<n;++i) {
+ p.println(" if(p"+i+" == null) {");
+ p.println(" if (other.p"+i+" != null)");
+ p.println(" return false;");
+ p.println(" } else if (!p"+i+".equals(other.p"+i+"))");
+ p.println(" return false;");
+ }
+ p.println(" return true;");
+ p.println(" }");
+ p.println();
}
p.println("}");
}
p.println(HEADER);
p.println("package " + PACKAGE + ";");
p.println();
+ p.println("import java.util.Arrays;");
+ p.println();
p.println("@SuppressWarnings(\"all\")");
p.println("public class UnsaturatedFunctionN implements Function {");
p.println(" private final Function f;");
p.println(" System.arraycopy(ops, 0, nps, ps.length, ops.length);");
p.println(" return f.applyArray(nps);");
p.println(" }");
+ p.println();
}
{
p.println(" @Override");
p.println(" sb.append(\")\");");
p.println(" return sb.toString();");
p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public int hashCode() {");
+ p.println(" return f.hashCode() + 31 * Arrays.hashCode(ps);");
+ p.println(" }");
+ p.println();
+ }
+ {
+ p.println(" @Override");
+ p.println(" public boolean equals(Object obj) {");
+ p.println(" if (this == obj)");
+ p.println(" return true;");
+ p.println(" if (obj == null)");
+ p.println(" return false;");
+ p.println(" if (getClass() != obj.getClass())");
+ p.println(" return false;");
+ p.println(" UnsaturatedFunctionN other = (UnsaturatedFunctionN) obj;");
+ p.println(" return f.equals(other.f) && Arrays.equals(ps, other.ps);");
+ p.println(" }");
+ p.println();
}
p.println("}");
}
instance Read String where
read str = str
-@deprecated
+@deprecated "Instead of 'splitString text pattern', write 'split pattern text' (note change in the parameter order)."
"`splitString text pattern` splits the string into a list of string where the parts are sepratated in the original list by the given pattern."
splitString :: String -> String -> [String]
splitString source pattern = arrayToList $ splitString_ source pattern
public static Object get(List l, double i) {
return l.get((int)i);
}
+
+ private static final FunctionImpl2 BUILD_FUNC = new FunctionImpl2() {
+ @Override
+ public Object apply(Object p0, Object p1) {
+ ((ArrayList)p0).add(p1);
+ return p0;
+ }
+ };
public static List build(Function f) {
- return (List)f.apply(new ArrayList(),
- new FunctionImpl2() {
- @Override
- public Object apply(Object p0, Object p1) {
- ((List)p0).add(p1);
- return p0;
- }
- });
+ return (List)f.apply(new ArrayList(), BUILD_FUNC);
}
public static List range(int from, int to) {
nps[i + 1] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction1 other = (UnsaturatedFunction1) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ return true;
+ }
+
}
nps[i + 2] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction2 other = (UnsaturatedFunction2) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ return true;
+ }
+
}
nps[i + 3] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction3 other = (UnsaturatedFunction3) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ return true;
+ }
+
}
nps[i + 4] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction4 other = (UnsaturatedFunction4) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ return true;
+ }
+
}
nps[i + 5] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction5 other = (UnsaturatedFunction5) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ return true;
+ }
+
}
nps[i + 6] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction6 other = (UnsaturatedFunction6) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ return true;
+ }
+
}
nps[i + 7] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ result = 31 * result + (p6 == null ? 0 : p6.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction7 other = (UnsaturatedFunction7) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ if(p6 == null) {
+ if (other.p6 != null)
+ return false;
+ } else if (!p6.equals(other.p6))
+ return false;
+ return true;
+ }
+
}
nps[i + 8] = ps[i];
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ int result = f.hashCode();
+ result = 31 * result + (p0 == null ? 0 : p0.hashCode());
+ result = 31 * result + (p1 == null ? 0 : p1.hashCode());
+ result = 31 * result + (p2 == null ? 0 : p2.hashCode());
+ result = 31 * result + (p3 == null ? 0 : p3.hashCode());
+ result = 31 * result + (p4 == null ? 0 : p4.hashCode());
+ result = 31 * result + (p5 == null ? 0 : p5.hashCode());
+ result = 31 * result + (p6 == null ? 0 : p6.hashCode());
+ result = 31 * result + (p7 == null ? 0 : p7.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunction8 other = (UnsaturatedFunction8) obj;
+ if(!f.equals(other.f))
+ return false;
+ if(p0 == null) {
+ if (other.p0 != null)
+ return false;
+ } else if (!p0.equals(other.p0))
+ return false;
+ if(p1 == null) {
+ if (other.p1 != null)
+ return false;
+ } else if (!p1.equals(other.p1))
+ return false;
+ if(p2 == null) {
+ if (other.p2 != null)
+ return false;
+ } else if (!p2.equals(other.p2))
+ return false;
+ if(p3 == null) {
+ if (other.p3 != null)
+ return false;
+ } else if (!p3.equals(other.p3))
+ return false;
+ if(p4 == null) {
+ if (other.p4 != null)
+ return false;
+ } else if (!p4.equals(other.p4))
+ return false;
+ if(p5 == null) {
+ if (other.p5 != null)
+ return false;
+ } else if (!p5.equals(other.p5))
+ return false;
+ if(p6 == null) {
+ if (other.p6 != null)
+ return false;
+ } else if (!p6.equals(other.p6))
+ return false;
+ if(p7 == null) {
+ if (other.p7 != null)
+ return false;
+ } else if (!p7.equals(other.p7))
+ return false;
+ return true;
+ }
+
}
*/
package org.simantics.scl.runtime.function;
+import java.util.Arrays;
+
@SuppressWarnings("all")
public class UnsaturatedFunctionN implements Function {
private final Function f;
System.arraycopy(ops, 0, nps, ps.length, ops.length);
return f.applyArray(nps);
}
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(")");
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ return f.hashCode() + 31 * Arrays.hashCode(ps);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ UnsaturatedFunctionN other = (UnsaturatedFunctionN) obj;
+ return f.equals(other.f) && Arrays.equals(ps, other.ps);
+ }
+
}
--- /dev/null
+package org.simantics.scl.runtime.reporting;
+
+import java.io.Writer;
+
+public class SCLReportingWriter extends Writer {
+
+ StringBuilder builder = null;
+
+ public SCLReportingWriter() {
+ builder = new StringBuilder();
+ }
+
+ @Override
+ public void close() {
+ flush();
+ }
+
+ @Override
+ public void flush() {
+ if (builder.length() > 0) {
+ SCLReporting.print(builder.toString());
+ builder.setLength(0);
+ }
+ }
+
+ @Override
+ public void write(char[] buf, int off, int len) {
+ if (len == 0) return;
+
+ if (len < 0) throw new IllegalArgumentException("Negative buffer region length");
+ if (off < 0) throw new IllegalArgumentException("Negative buffer region offset");
+ if (off + len > buf.length) throw new IllegalArgumentException("Buffer region overflow");
+
+ for (int i = 0; i < len; i++) {
+ if (buf[off + i] == '\n') {
+ SCLReporting.print(builder.toString());
+ builder.setLength(0);
+ }
+ else {
+ builder.append(buf[off + i]);
+ }
+ }
+ }
+}
import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
import org.simantics.scl.compiler.internal.parsing.parser.SCLParserImpl;
import org.simantics.scl.compiler.module.ImportDeclaration;
+import org.simantics.scl.compiler.module.InvalidModulePathException;
import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.compiler.module.ModuleUtils;
import org.simantics.scl.compiler.module.repository.ImportFailureException;
import org.simantics.scl.compiler.types.TCon;
import org.simantics.scl.osgi.SCLOsgi;
private ArrayList<ImportDeclaration> processRelativeImports(List<ImportDeclaration> relativeImports) {
ArrayList<ImportDeclaration> absoluteImports = new ArrayList<ImportDeclaration>(relativeImports.size());
for(ImportDeclaration relativeImport : relativeImports) {
- if(relativeImport.moduleName.startsWith(".")) {
- String absoluteModuleName = convertRelativeModulePath(relativeImport.moduleName);
- if(absoluteModuleName != null)
- absoluteImports.add(new ImportDeclaration(
- absoluteModuleName, relativeImport.localName,
- relativeImport.reexport, relativeImport.spec));
- }
- else
- absoluteImports.add(relativeImport);
+ try {
+ String absoluteModuleName = ModuleUtils.resolveAbsolutePath(moduleName, relativeImport.moduleName);
+ absoluteImports.add(new ImportDeclaration(
+ absoluteModuleName, relativeImport.localName,
+ relativeImport.reexport, relativeImport.spec));
+ } catch (InvalidModulePathException e) {
+ // Nothing to do
+ }
}
return absoluteImports;
}
- private String convertRelativeModulePath(String relativeModuleName) {
- String originalRelativeModuleName = relativeModuleName;
- int p = moduleName.lastIndexOf('/');
- String parentPackage = p < 0 ? "" : moduleName.substring(0, p);
- while(relativeModuleName.startsWith(".")) {
- if(relativeModuleName.startsWith("./")) {
- relativeModuleName = relativeModuleName.substring(2);
- }
- else if(relativeModuleName.startsWith("../")) {
- relativeModuleName = relativeModuleName.substring(3);
- if(parentPackage.isEmpty()) {
- System.err.println("Couldn't resolve the relative module name " + originalRelativeModuleName + " when the current module name is " + moduleName + ".");
- return null;
- }
- p = parentPackage.lastIndexOf('/');
- parentPackage = p < 0 ? "" : parentPackage.substring(0, p);
- }
- else {
- System.err.println("Couldn't resolve the relative module name " + originalRelativeModuleName + ". It has an invalid syntax.");
- return null;
- }
- }
- return parentPackage + "/" + relativeModuleName;
- }
-
private static final Comparator<SCLCompletionProposal> COMPARATOR = new Comparator<SCLCompletionProposal>() {
@Override
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.module.InvalidModulePathException;
+import org.simantics.scl.compiler.module.ModuleUtils;
+import org.simantics.scl.compiler.source.ModuleSource;
+import org.simantics.scl.osgi.SCLOsgi;
import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment;
public class OpenDeclaration extends AbstractHandler {
if(lineAtCaret.startsWith("import ") || lineAtCaret.startsWith("include ")) {
int p1 = lineAtCaret.indexOf('"', 6);
int p2 = lineAtCaret.indexOf('"', p1+1);
- String moduleName = lineAtCaret.substring(p1+1, p2);
- OpenSCLModule.openModule(moduleName);
+ SCLModuleEditorInput input = (SCLModuleEditorInput)moduleEditor.getEditorInput();
+ try {
+ String moduleName = ModuleUtils.resolveAbsolutePath(input.getModuleName(), lineAtCaret.substring(p1+1, p2));
+ ModuleSource source = SCLOsgi.SOURCE_REPOSITORY.getModuleSource(moduleName, null);
+ if (source != null) {
+ OpenSCLModule.openModule(moduleName);
+ }
+ } catch (InvalidModulePathException e) {
+ // Nothing to do
+ }
}
else {
// Try to find an identifier at caret
SEL.StandardPropertyInfo.CategorySortingName ""
SEL.StandardPropertyInfo.IsHidden true
-SEL.getSpecialCategory ==> "Resource -> <ReadGraph> Resource" <R L0.HasProperty : L0.FunctionalRelation
+SEL.getSpecialCategory ==> "Resource -> <ReadGraph> Maybe Resource" <R L0.HasProperty : L0.FunctionalRelation
SEL.ColorParameterType <T SEL.GenericParameterType
@L0.assert SEL.HasDisplayValue
@L0.new
L0.HasResourceClass "org.simantics.selectionview.ui.ontology.SelectionViewUIResources"
+SEL.SCLMain : L0.SCLModule
+ L0.SCLModule.definition _ : L0.String
+ @L0.loadString "scl/SCLMain.scl"
+
SEL.CategoryNode : VP.NodeType
VP.HasContentType "org.simantics.selectionview.CategoryNode"
VP.HasBundle "org.simantics.selectionview"
VP.ChildContribution.HasChildNodeType SEL.CategoryNode
VP.ChildContribution.HasRule
SEL.StandardProperties.BrowseContextStandardChildren.Cat : SEL.VariablePropertyCategoryRule
+ @MOD.scl SEL_BASE.getSpecialCategory "layer0Categories" "Resource -> <ReadGraph> Maybe Resource"
@L0.assert VP.BrowseContext.HasVisualsContribution
_ : VP.VisualsContribution
VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
VP.VisualsContribution.HasRule
SEL.StandardProperties.BrowseContextStandardChildren.Sorter : SEL.StandardPropertySorterRuleType
+ @MOD.scl SEL_BASE.getSpecialCategory "layer0Categories" "Resource -> <ReadGraph> Maybe Resource"
+ @L0.assert VP.BrowseContext.HasVisualsContribution
+ _ : VP.VisualsContribution
+ VP.VisualsContribution.HasNodeType MOD.ModelingBrowseContext.Variable
+ VP.VisualsContribution.HasRule VP.DescriptionTooltipRule
SEL.StandardProperties.BrowseContextWithoutChildren <T VP.BrowseContext
@L0.assert VP.BrowseContext.HasVisualsContribution
--- /dev/null
+include "Simantics/All"
+
+layer0Categories :: Resource -> <ReadGraph> Maybe Resource
+layer0Categories predicate = match predicate with
+ L0.HasName -> Just MOD.SystemPropertyInfo
+ _ -> Nothing
+
\ No newline at end of file
public final Resource CategoryNode;
public final Resource CategoryNodeLabelRule;
public final Resource PropertyColumn;
+ public final Resource SCLMain;
public final Resource StandardProperties;
public final Resource StandardPropertiesBase;
public final Resource StandardPropertiesBase_BrowseContext;
public static final String CategoryNode = "http://www.simantics.org/SelectionViewUI-1.1/CategoryNode";
public static final String CategoryNodeLabelRule = "http://www.simantics.org/SelectionViewUI-1.1/CategoryNodeLabelRule";
public static final String PropertyColumn = "http://www.simantics.org/SelectionViewUI-1.1/PropertyColumn";
+ public static final String SCLMain = "http://www.simantics.org/SelectionViewUI-1.1/SCLMain";
public static final String StandardProperties = "http://www.simantics.org/SelectionViewUI-1.1/StandardProperties";
public static final String StandardPropertiesBase = "http://www.simantics.org/SelectionViewUI-1.1/StandardPropertiesBase";
public static final String StandardPropertiesBase_BrowseContext = "http://www.simantics.org/SelectionViewUI-1.1/StandardPropertiesBase/BrowseContext";
CategoryNode = getResourceOrNull(graph, URIs.CategoryNode);
CategoryNodeLabelRule = getResourceOrNull(graph, URIs.CategoryNodeLabelRule);
PropertyColumn = getResourceOrNull(graph, URIs.PropertyColumn);
+ SCLMain = getResourceOrNull(graph, URIs.SCLMain);
StandardProperties = getResourceOrNull(graph, URIs.StandardProperties);
StandardPropertiesBase = getResourceOrNull(graph, URIs.StandardPropertiesBase);
StandardPropertiesBase_BrowseContext = getResourceOrNull(graph, URIs.StandardPropertiesBase_BrowseContext);
org.simantics.modeling.ontology;bundle-version="1.2.0",
org.simantics.fastlz;bundle-version="1.2.1",
org.apache.commons.compress;bundle-version="1.7.0",
- org.simantics.lz4;bundle-version="1.3.0"
+ org.simantics.lz4;bundle-version="1.3.0",
+ org.slf4j.api;bundle-version="1.7.0"
Export-Package: org.simantics.simulation,
org.simantics.simulation.data,
org.simantics.simulation.experiment,
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.request.ExternalRead;
import org.simantics.utils.datastructures.ListenerList;
public abstract class Experiment implements IExperiment {
@Override
public ExperimentState getState(ReadGraph graph) throws DatabaseException {
- throw new UnsupportedOperationException();
+ return graph.syncRequest(EXPERIMENT_STATE_READ);
}
public void changeState(ExperimentState newState) {
return identifier;
}
+ static class ExperimentStateRead implements ExternalRead<ExperimentState>, Runnable {
+
+ final private Experiment experiment;
+ private Listener<ExperimentState> listener = null;
+
+ ExperimentStateRead(Experiment experiment) {
+ this.experiment = experiment;
+ }
+
+ @Override
+ public void register(ReadGraph graph, final Listener<ExperimentState> procedure) {
+ //System.out.println("IcTrackerRequest.register: " + procedure);
+ listener = procedure;
+ procedure.execute(experiment.state);
+ }
+
+ @Override
+ public void unregistered() {
+ //System.out.println("IcTrackerRequest.unregister: " + listener);
+ listener = null;
+ }
+
+ @Override
+ public void run() {
+ Listener<ExperimentState> l = listener;
+ //System.out.println("IcTrackerRequest.run: " + l);
+ if (l != null)
+ l.execute(experiment.state);
+ }
+ }
+
+ private ExperimentStateRead EXPERIMENT_STATE_READ = new ExperimentStateRead(this);
+
}
((IDynamicExperiment)experiment).simulate(enabled);
}
+ public static ExperimentState getExperimentState(ReadGraph graph, IExperiment experiment) throws DatabaseException {
+ return experiment.getState(graph);
+ }
+
public static void disposeExperiment(final IExperiment experiment) {
if(experiment instanceof IDynamicExperiment) {
import org.simantics.simulation.model.IModel;
import org.simantics.ui.workbench.WorkbenchShutdownService;
import org.simantics.utils.datastructures.ListenerList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Simple local ExperimentManager implementation
*/
public class ExperimentManager implements IExperimentManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ExperimentManager.class);
+
CopyOnWriteArrayList<IExperimentManagerListener> listeners = new CopyOnWriteArrayList<IExperimentManagerListener>();
ListenerList<IExperiment> experiments = new ListenerList<IExperiment>(IExperiment.class);
IExperiment activeExperiment;
if (!listeners.isEmpty()) {
// Some clients are leaking listeners. Shame on them.
- System.err.println("ExperimentManager still contains the following listeners after disposal:");
+ LOGGER.warn("ExperimentManager still contains the following listeners after disposal:");
for (IExperimentManagerListener listener : listeners)
- System.err.println("\t" + listener);
+ LOGGER.warn("\t" + listener);
}
}
}
*******************************************************************************/
package org.simantics.spreadsheet.common;
+import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontData;
+import org.simantics.document.server.io.IFont;
import org.simantics.document.server.io.ITreeTableCell;
+import org.simantics.document.server.io.SimpleFont;
public class TreeTableCell extends TableCell implements ITreeTableCell {
private int parent = -1;
+
+ private boolean editable = true;
+ private Object data;
public TreeTableCell() {
}
+ public TreeTableCell(String text, Object data, Object font, int parent, int row, int column, boolean editable) {
+ super(column, row, 0, 0, text, (IFont)font, null, null, false, 1, 1);
+ this.editable = editable;
+ this.parent = parent;
+ this.data = data;
+ }
+
+ public static TreeTableCell createTreeTableCell(String text, Object data, Object font, int parent, int row, int column, boolean editable) {
+ return new TreeTableCell(text, data, extractIFont(font), parent, row, column, editable);
+ }
+
+ private static IFont extractIFont(Object font) {
+ if(font instanceof FontDescriptor) {
+ FontDescriptor descriptor = (FontDescriptor)font;
+ String family = "";
+ String style = "";
+ int size = 12;
+ for(FontData d : descriptor.getFontData()) {
+ System.err.println("data: " + d);
+ family = d.getName();
+ if((d.getStyle() & SWT.ITALIC) != 0) style += "Italic";
+ if((d.getStyle() & SWT.BOLD) != 0) style += "Bold";
+ size = d.getHeight();
+ }
+ return new SimpleFont(family, style, size);
+ }
+ return null;
+ }
+
public void setParent(int parent) {
this.parent = parent;
}
return parent;
}
+ @Override
+ public Object getData() {
+ return data;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
+
}
}
@Override
- public Optional<Resource> perform(Resource parent, Path file) {
- return Optional.empty();
+ public Optional<Resource> perform(Resource parent, Path file) throws Exception {
+ throw new UnsupportedOperationException("Excel import is not yet supported");
}
@Override
importJava "org.simantics.spreadsheet.common.TreeTableCell" where
data TreeTableCell
+ @JavaName getData
+ getTreeTableCellData :: TreeTableCell -> <Proc> a
+
+ createTreeTableCell :: String -> a -> Maybe b -> Integer -> Integer -> Integer -> Boolean -> <Proc> TreeTableCell
+
+ @JavaName getText
+ treeTableCellText :: TreeTableCell -> <Proc> String
+ @JavaName getFont
+ treeTableCellFont :: TreeTableCell -> <Proc> Maybe IFont
+ @JavaName getRow
+ treeTableCellRow :: TreeTableCell -> <Proc> Integer
+ @JavaName getColumn
+ treeTableCellColumn :: TreeTableCell -> <Proc> Integer
+
importJava "org.simantics.spreadsheet.common.SpreadsheetCell" where
data SpreadsheetCell
public <S> S getConcreteSolver() {
return handler.solver.getConcreteSolver();
}
-
+
+ public String getModuleType() {
+ return updater != null ? updater.moduleType : null;
+ }
+
public String getModuleName() {
return component.solverComponentName;
}
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
-import org.simantics.ui.utils.ResourceAdaptionUtils;
+import org.simantics.ui.selection.WorkbenchSelectionUtils;
import org.simantics.ui.workbench.action.ResourceEditorAdapterAction;
import org.simantics.ui.workbench.editor.EditorAdapter;
import org.simantics.ui.workbench.editor.EditorRegistry;
}
protected Object extractResource(ReadGraph graph, Object object) throws DatabaseException {
- Resource resource = ResourceAdaptionUtils.adaptToResource(graph, object);
+ Resource resource = WorkbenchSelectionUtils.getPossibleResource(object);
+ //Resource resource = ResourceAdaptionUtils.adaptToResource(graph, object);
if(resource != null) return resource;
else return object;
}
import org.simantics.project.IProject;
import org.simantics.ui.SimanticsUI;
import org.simantics.ui.icons.ImageUtil;
+import org.simantics.ui.selection.WorkbenchSelectionUtils;
import org.simantics.ui.utils.ResourceAdaptionUtils;
import org.simantics.utils.datastructures.persistent.ContextMap;
}
@Override
- protected IAction[] getActions(ReadGraph g, Object[] selection) {
+ protected IAction[] getActions(ReadGraph g, Object[] selection) throws DatabaseException {
if(selection.length == 1) {
- final Resource r = ResourceAdaptionUtils.adaptToResource(selection[0]);
+ final Resource r = WorkbenchSelectionUtils.getPossibleResource(selection[0]);
if(r == null)
return NO_ACTIONS;
try {
}
public static Resource getPossibleResource(RequestProcessor processor, Object input, Resource type) throws DatabaseException {
- if(input instanceof Collection && !((Collection)input).isEmpty()) {
- Object element = ((Collection)input).iterator().next();
+ if(input instanceof Collection && !((Collection<?>)input).isEmpty()) {
+ Object element = ((Collection<?>)input).iterator().next();
if(element instanceof Resource)
return (Resource)element;
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
private static final String ATTR_ID = "id";
-
+ private static final Comparator<EditorAdapter> ADAPTER_COMPARATOR = (o1, o2) -> -(o1.getPriority() - o2.getPriority());
+
private static class Group {
public final String id;
public final List<EditorAdapterDescriptor> adapters;
}
result = gatherAdapterResult(l);
+
+ Arrays.sort(result, ADAPTER_COMPARATOR);
+
updateCache(r, result);
if (status != null && !status.isOK())
*******************************************************************************/
package org.simantics.utils.datastructures;
-public interface BinaryCallback<T1, T2> {
+import java.util.function.BiConsumer;
+
+/**
+ * @deprecated use {@link BiConsumer} instead
+ */
+@Deprecated
+public interface BinaryCallback<T1, T2> extends BiConsumer<T1, T2> {
void run(T1 arg1, T2 arg2);
-
+
+ @Override
+ default void accept(T1 arg, T2 arg2) {
+ run(arg, arg2);
+ }
+
}
*/
@Deprecated
@FunctionalInterface
-public interface Callable<T> {
+public interface Callable<T> extends Supplier<T> {
public T call();
+ @Override
+ default T get() {
+ return call();
+ }
+
}
import java.io.PrintStream;
import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
/**
}
}
- public static class PrintCallback implements BinaryCallback<Long, TimeUnit> {
+ public static class PrintCallback implements BiConsumer<Long, TimeUnit> {
String task;
PrintStream stream;
PrintCallback(String task) {
this.stream = stream;
}
@Override
- public void run(Long arg1, TimeUnit arg2) {
+ public void accept(Long arg1, TimeUnit arg2) {
stream.println(task + " took " + arg1 + " " + arg2.toString());
}
};
time(runnable, reportTimeUnit, new PrintCallback(runnable.toString(), stream));
}
- public static void time(Runnable runnable, TimeUnit reportTimeUnit, BinaryCallback<Long, TimeUnit> result) {
+ public static void time(Runnable runnable, TimeUnit reportTimeUnit, BiConsumer<Long, TimeUnit> result) {
long start = System.nanoTime();
runnable.run();
long end = System.nanoTime();
- result.run(reportTimeUnit.convert(end-start, TimeUnit.NANOSECONDS), reportTimeUnit);
+ result.accept(reportTimeUnit.convert(end-start, TimeUnit.NANOSECONDS), reportTimeUnit);
}
}
*******************************************************************************/
package org.simantics.utils.datastructures;
-public interface UnaryFunction<R, A> {
+import java.util.function.Function;
+
+/**
+ * @deprecated use {@link Function} instead
+ */
+@Deprecated
+public interface UnaryFunction<R, A> extends Function<A, R> {
public R call(A arg);
-
+
+ @Override
+ default R apply(A t) {
+ return call(t);
+ }
+
}
public class SWTThread implements IThreadWorkQueue, Executor {
- final Display display;
+ private final Display display;
+ private final boolean executeAsync;
+
+ public static IThreadWorkQueue getThreadAccess(Display display, boolean executeAsync)
+ {
+ return new SWTThread(display, executeAsync);
+ }
public static IThreadWorkQueue getThreadAccess(Display display)
{
- return new SWTThread(display);
+ return getThreadAccess(display, false);
}
public static IThreadWorkQueue getThreadAccess(Widget widget)
{
- return new SWTThread(widget.getDisplay());
+ return new SWTThread(widget.getDisplay(), false);
}
public static IThreadWorkQueue getThreadAccess() {
- return new SWTThread(Display.getDefault());
+ return new SWTThread(Display.getDefault(), false);
}
- SWTThread(Display display)
+ SWTThread(Display display, boolean executeAsync)
{
this.display = display;
+ this.executeAsync = executeAsync;
}
@Override
@Override
public void execute(Runnable command) {
- syncExec(command);
+ if (executeAsync) asyncExec(command);
+ else syncExec(command);
}
}
Export-Package: org.simantics.utils.threads,
org.simantics.utils.threads.logger
Bundle-Vendor: VTT Technical Research Centre of Finland
-Require-Bundle: org.eclipse.swt;bundle-version="3.6.0";resolution:=optional
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * VTT Technical Research Centre of Finland - initial API and implementation
- *******************************************************************************/
-package org.simantics.utils.threads;
-
-import java.util.concurrent.Executor;
-
-import org.eclipse.swt.widgets.Display;
-
-public class Executors2 {
-
- public static Executor createSWTExecutor(Display display, boolean async) {
- return async ? new SWTExecutorAsync(display) : new SWTExecutorSync(display);
- }
-
-}
-
-class SWTExecutorAsync implements Executor {
-
- Display display;
- public SWTExecutorAsync(Display display)
- {
- this.display = display;
- }
-
- @Override
- public void execute(Runnable command) {
- // Don't accept work if the SWT thread is disposed.
- if (display.isDisposed())
- throw new RuntimeException("The SWT thread has been disposed");
- display.asyncExec(command);
- }
-
-}
-
-class SWTExecutorSync implements Executor {
-
- Display display;
- public SWTExecutorSync(Display display)
- {
- this.display = display;
- }
-
- @Override
- public void execute(Runnable command) {
- // Don't accept work if the SWT thread is disposed.
- if (display.isDisposed())
- throw new RuntimeException("The SWT thread has been disposed");
- display.syncExec(command);
- }
-
-}
-
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.utils.ui.dialogs;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IconAndMessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class InfoDialog extends IconAndMessageDialog {
+
+ private String title;
+ private Text messageText;
+
+ protected InfoDialog(Shell parentShell, String title, String message) {
+ super(parentShell);
+ this.title = title;
+ this.message = message;
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ @Override
+ protected Image getImage() {
+ return getInfoImage();
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(title);
+ newShell.setImage(newShell.getDisplay().getSystemImage(SWT.ICON_INFORMATION));
+ }
+
+ protected Control createMessageArea(Composite composite) {
+ // create image
+ Image image = getImage();
+ if (image != null) {
+ imageLabel = new Label(composite, SWT.NULL);
+ image.setBackground(imageLabel.getBackground());
+ imageLabel.setImage(image);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING)
+ .applyTo(imageLabel);
+ }
+ // create message
+ if (message != null) {
+ messageText = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.FLAT | SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL);
+ messageText.setEditable(false);
+ messageText.setText(message);
+ GridDataFactory
+ .fillDefaults()
+ .grab(true, true)
+ .hint(
+ convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
+ SWT.DEFAULT).applyTo(messageText);
+ }
+ return composite;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ createMessageArea(composite);
+
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+ layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+ layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+ layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+ layout.numColumns = 2;
+ composite.setLayout(layout);
+ GridData childData = new GridData(GridData.FILL_BOTH);
+ childData.horizontalSpan = 2;
+ childData.grabExcessVerticalSpace = true;
+ composite.setLayoutData(childData);
+ applyDialogFont(composite);
+
+ return composite;
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ // create OK button by default
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+ true);
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ super.buttonPressed(buttonId);
+ }
+
+ public static boolean open(Shell parent, String title, String message, int style) {
+ InfoDialog dialog = new InfoDialog(parent, title, message);
+ style &= SWT.SHEET;
+ dialog.setShellStyle(dialog.getShellStyle() | style);
+ return dialog.open() == 0;
+ }
+
+}
\ No newline at end of file
}
}
+ @FunctionalInterface
+ public static interface FileOperation {
+ IOperation<Boolean, IOException> perform(File file);
+
+ default void perform(File... files) {
+ for (File f : files)
+ perform(f);
+ }
+ }
+
+ public static class DeleteOperation implements FileOperation {
+ private final FileService service;
+ private final DeleteOption[] options;
+
+ public DeleteOperation(FileService service, DeleteOption... options) {
+ this.service = service;
+ this.options = options;
+ }
+
+ @Override
+ public IOperation<Boolean, IOException> perform(File file) {
+ return service.scheduleDeleteIfExists(file, options);
+ }
+ }
+
/**
* Schedules a file to be deleted at some point in the future when the
* system allows it to be deleted if ever.
*/
IOperation<Boolean, IOException> scheduleDeleteIfExists(File file, DeleteOption... options);
+ /**
+ * @param options
+ * the deletion options to be used by the returned FileOperation
+ * @return a FileOperation that runs
+ * {@link #scheduleDeleteIfExists(File, DeleteOption...)} for any
+ * files given to it
+ * @since 1.28.0
+ */
+ default FileOperation deleteOperation(DeleteOption... options) {
+ return new DeleteOperation(this, options);
+ }
+
}
}
}
} else if (dir.exists()) {
- if (filter.contains(dir.getAbsolutePath())) {
+ if (!filter.contains(dir.getAbsolutePath())) {
if (!dir.delete()) {
throw new IOException("Could not delete file: " + dir.getAbsolutePath());
}
return FileVisitResult.CONTINUE;
}
}
+
+ public static void syncFile(File file) throws IOException {
+ try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+ raf.getFD().sync();
+ }
+ }
}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTButton;
-
-public class ButtonLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public ButtonLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTButton node = parent.addNode(SWTButton.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextContainer_HasText, node.getTextFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Button_Modifier, node.getModifierFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Button_HasImage, node.getImageFunction());
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTCCombo;
-
-public class CComboLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public CComboLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTCCombo node = parent.addNode(SWTCCombo.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_AvailableItems, node.getAvailableFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_SelectedItem, node.getSelectionFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_Modifier, node.getModifierFunction());
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTCombo;
-
-public class ComboLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public ComboLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTCombo node = parent.addNode(SWTCombo.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_AvailableItems, node.getAvailableFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_SelectedItem, node.getSelectionFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Combo_Modifier, node.getModifierFunction());
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.datatypes.literal.RGB;
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTComposite;
-
-public class CompositeLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public CompositeLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTComposite node = parent.addNode(SWTComposite.class);
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasBackground, RGB.Integer.BINDING, node.getBackgroundFunction());
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setLayout(LoaderUtils.getLayout(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.TreeItem;
-import org.simantics.browsing.ui.BuiltinKeys;
-import org.simantics.browsing.ui.NodeContext;
-import org.simantics.databoard.Bindings;
-import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
-import org.simantics.db.VirtualGraph;
-import org.simantics.db.WriteGraph;
-import org.simantics.db.common.request.ResourceRead;
-import org.simantics.db.common.request.WriteRequest;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.util.Simantics;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ViewUtils;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTExplorer;
-
-public class ExplorerLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public ExplorerLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, final Variable context) throws DatabaseException {
-
- SWTExplorer node = parent.addNode(SWTExplorer.class);
-
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- String browseContextURI = Simantics.getSession().sync(new ResourceRead<String>(configuration) {
-
- @Override
- public String perform(ReadGraph graph) throws DatabaseException {
- ViewsResources VIEW = ViewsResources.getInstance(graph);
- Resource browseContext = graph.getSingleObject(resource, VIEW.Explorer_BrowseContext);
- return graph.getURI(browseContext);
- }
-
- });
-
- node.setBrowseContextURI(browseContextURI);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
-
- node.setColumns(LoaderUtils.getColumns(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Explorer_InputTransformation, node.getInputFunction());
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Explorer_HasColumnsVisible, node.getColumnsVisibleFunction());
-
- Listener selectionListener = Simantics.getSession().sync(new ResourceRead<Listener>(configuration) {
-
- @Override
- public Listener perform(ReadGraph graph) throws DatabaseException {
- ViewsResources VIEW = ViewsResources.getInstance(graph);
- Resource listener = graph.getPossibleObject(resource, VIEW.Explorer_SelectionListener);
- if(listener == null) return null;
- return graph.adapt(listener, Listener.class);
- }
-
- });
-
- if(selectionListener != null) node.addListenerToControl(SWT.Selection, selectionListener);
-
- node.addListenerToControl(SWT.Selection, new Listener() {
-
- @Override
- public void handleEvent(Event event) {
-
- TreeItem item = (TreeItem)event.item;
-// Tree tree = item.getParent();
-// GraphExplorer explorer = (GraphExplorer)tree.getData("GraphExplorer");
-// final Resource runtimeDiagram = (Resource)explorer.getRoot().getConstant(BuiltinKeys.INPUT);
-// final boolean checked = item.getChecked();
- NodeContext nc = (NodeContext)item.getData();
- Object obj = nc.getConstant(BuiltinKeys.INPUT);
-
- if (obj instanceof Variable) {
- final Variable var = (Variable) obj;
- Simantics.getSession().async(new WriteRequest(Simantics.getSession().getService(VirtualGraph.class)) {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- ViewsResources VIEW = ViewsResources.getInstance(graph);
- System.err.println("setParameter " + context.getURI(graph) + " -> " + var.getURI(graph));
- ViewUtils.setParameter(graph, context, VIEW.Explorer_Selection, var.getURI(graph), Bindings.STRING);
- }
- });
- }
- }
-
- });
-
- return node;
-
- }
-
-}
-
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTLabel;
-
-public class LabelLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public LabelLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTLabel node = parent.addNode(SWTLabel.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextContainer_HasText, node.getTextFunction());
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTScrolledComposite;
-
-public class ScrolledCompositeLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public ScrolledCompositeLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTScrolledComposite node = parent.addNode(SWTScrolledComposite.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setLayout(LoaderUtils.getLayout(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.swt.custom.CTabItem;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
-import org.simantics.db.common.request.UniqueRead;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.util.Simantics;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTTabFolder;
-
-public class TabFolderLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public TabFolderLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTTabFolder node = parent.addNode(SWTTabFolder.class);
-
- final Collection<Variable> children = LoaderUtils.getChildren(configuration);
-
- String[] names = Simantics.getSession().sync(new UniqueRead<String[]>() {
-
- @Override
- public String[] perform(ReadGraph graph) throws DatabaseException {
-
- String[] result = new String[children.size()];
-
- int index = 0;
- for(Variable child : children) {
- result[index++] = child.getPropertyValue(graph, Variables.LABEL);
- }
-
- return result;
-
- }
-
- });
-
- node.setTabNames(names);
-
- return node;
-
- }
-
- Set<Control> getControls(CTabItem item) {
- HashSet<Control> result = new HashSet<Control>();
- forControl(item.getControl(), result);
- return result;
- }
-
- void forControl(Control control, HashSet<Control> controls) {
- controls.add(control);
- if(control instanceof Composite) {
- Composite composite = (Composite)control;
- for(Control child : composite.getChildren()) forControl(child, controls);
- }
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.datatypes.literal.Font;
-import org.simantics.datatypes.literal.RGB;
-import org.simantics.db.Resource;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTText;
-
-public class TextLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public TextLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, Variable context) throws DatabaseException {
-
- SWTText node = parent.addNode(SWTText.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextContainer_HasText, node.getTextFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasBackground, RGB.Integer.BINDING, node.getBackgroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasForeground, RGB.Integer.BINDING, node.getForegroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasFont, Font.BINDING, node.getFontFunction());
-
- return node;
-
- }
-
-}
+++ /dev/null
-package org.simantics.views.swt.loader;
-
-import org.simantics.databoard.Bindings;
-import org.simantics.datatypes.literal.Font;
-import org.simantics.datatypes.literal.RGB;
-import org.simantics.db.Resource;
-import org.simantics.db.VirtualGraph;
-import org.simantics.db.WriteGraph;
-import org.simantics.db.common.request.WriteRequest;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.util.Simantics;
-import org.simantics.db.layer0.variable.Variable;
-import org.simantics.scenegraph.ParentNode;
-import org.simantics.scenegraph.loader.ScenegraphLoader;
-import org.simantics.utils.ui.widgets.TrackedModifyEvent;
-import org.simantics.utils.ui.widgets.TrackedModifyListener;
-import org.simantics.views.ViewUtils;
-import org.simantics.views.ontology.ViewsResources;
-import org.simantics.views.swt.client.base.ISWTViewNode;
-import org.simantics.views.swt.client.impl.SWTTrackedText;
-
-public class TrackedTextLoader implements ScenegraphLoader {
-
- final private Resource configuration;
-
- public TrackedTextLoader(Resource configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public ISWTViewNode create(ParentNode<ISWTViewNode> parent, final Variable context) throws DatabaseException {
-
- SWTTrackedText node = parent.addNode(SWTTrackedText.class);
-
- node.setLayoutData(LoaderUtils.getGridData(configuration));
- node.setStyle(LoaderUtils.getStyle(configuration));
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextContainer_HasText, node.getTextFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasForeground, RGB.Integer.BINDING, node.getForegroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TrackedText_HasInvalidBackground, RGB.Integer.BINDING, node.getInvalidBackgroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TrackedText_HasInactiveBackground, RGB.Integer.BINDING, node.getInactiveBackgroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TrackedText_HasHoverBackground, RGB.Integer.BINDING, node.getHoverBackgroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TrackedText_HasEditingBackground, RGB.Integer.BINDING, node.getEditingBackgroundFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.Control_HasFont, Font.BINDING, node.getFontFunction());
-
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextReceiver_Modifier, node.getModifierFunction());
- LoaderUtils.listen(configuration, context, ViewsResources.URIs.TextReceiver_Validator, node.getValidatorFunction());
-
- node.addModifyListener(new TrackedModifyListener() {
-
- @Override
- public void modifyText(TrackedModifyEvent e) {
-
- final String text = e.getText();
-
- Simantics.getSession().async(new WriteRequest(Simantics.getSession().getService(VirtualGraph.class)) {
-
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- ViewsResources VIEW = ViewsResources.getInstance(graph);
- System.err.println("setParameter " + context.getURI(graph) + " -> " + text);
- ViewUtils.setParameter(graph, context, VIEW.TrackedText_Content, text, Bindings.STRING);
- }
-
- });
-
- }
-
- });
-
- return node;
-
- }
-
-}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>org.simantics.views.text.ontology</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.simantics.graph.builder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.pde.ManifestBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.pde.SchemaBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.pde.PluginNature</nature>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ <nature>org.simantics.graph.nature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: http://www.simantics.org/TextViews
+Bundle-SymbolicName: org.simantics.views.text.ontology
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Semantum Oy
+Require-Bundle: org.simantics.layer0,
+ org.simantics.views.ontology;bundle-version="1.2.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
--- /dev/null
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+ .,\\r
+ graph.tg\r
+src.includes = graph/\r
--- /dev/null
+L0 = <http://www.simantics.org/Layer0-1.1>
+VIEWS = <http://www.simantics.org/Views-1.2>
+
+TEXTVIEWS = <http://www.simantics.org/TextViews-1.0> : L0.Ontology
+ @L0.new
+
+TEXTVIEWS.MarkupSourceViewer <T VIEWS.StyledText
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>org.simantics.views.text</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ <buildCommand>\r
+ <name>org.eclipse.jdt.core.javabuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.pde.ManifestBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ <buildCommand>\r
+ <name>org.eclipse.pde.SchemaBuilder</name>\r
+ <arguments>\r
+ </arguments>\r
+ </buildCommand>\r
+ </buildSpec>\r
+ <natures>\r
+ <nature>org.eclipse.pde.PluginNature</nature>\r
+ <nature>org.eclipse.jdt.core.javanature</nature>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Modelled Text Viewer UI Controls
+Bundle-SymbolicName: org.simantics.views.text;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.views.text.internal.Activator
+Bundle-Vendor: Semantum Oy
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.ui.editors;bundle-version="3.9.0",
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text;bundle-version="3.10.0",
+ org.eclipse.mylyn.wikitext.core;bundle-version="2.7.0",
+ org.eclipse.mylyn.wikitext.mediawiki.core;bundle-version="2.7.0",
+ org.eclipse.mylyn.wikitext.ui;bundle-version="2.7.0",
+ org.eclipse.mylyn.wikitext.mediawiki.ui;bundle-version="2.7.0",
+ org.simantics.views;bundle-version="1.1.0",
+ org.simantics.views.swt;bundle-version="1.0.0",
+ org.simantics.views.swt.client;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2017 Association for Decentralized Information Management
+ in Industry THTH ry.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Semantum Oy - initial API and implementation
+ -->
+<adapters>
+
+ <target interface="org.simantics.scenegraph.loader.ScenegraphLoader">
+ <type uri="http://www.simantics.org/TextViews-0.0/MarkupSourceViewer" class="org.simantics.scenegraph.loader.StandardScenegraphLoader">
+ <this/>
+ <bundle />
+ <string>org.simantics.views.text.internal.SWTMarkupSourceViewer</string>
+ </type>
+ </target>
+
+</adapters>
--- /dev/null
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+ .,\\r
+ adapters.xml,\\r
+ plugin.xml\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+ Copyright (c) 2017 Association for Decentralized Information Management in
+ Industry THTH ry.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Semantum Oy - (#7066) undo/redo support for markup editor
+ -->
+
+<plugin>
+
+ <extension
+ point="org.eclipse.core.expressions.definitions">
+ <definition
+ id="org.simantics.views.text.inTextViewer">
+ <with variable="activeFocusControlId">
+ <equals value="inTextViewer"/>
+ </with>
+ </definition>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.simantics.views.text.internal.TextViewerUndoHandler:undo"
+ commandId="org.eclipse.ui.edit.undo">
+ <activeWhen>
+ <reference definitionId="org.simantics.views.text.inTextViewer" />
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.simantics.views.text.internal.TextViewerUndoHandler:redo"
+ commandId="org.eclipse.ui.edit.redo">
+ <activeWhen>
+ <reference definitionId="org.simantics.views.text.inTextViewer" />
+ </activeWhen>
+ </handler>
+ </extension>
+
+</plugin>
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.views.text.internal;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.simantics.views.text"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - (#7066) initial API and implementation
+ *******************************************************************************/
+package org.simantics.views.text.internal;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
+import org.eclipse.mylyn.wikitext.mediawiki.core.MediaWikiLanguage;
+import org.eclipse.mylyn.wikitext.ui.editor.MarkupSourceViewer;
+import org.eclipse.mylyn.wikitext.ui.editor.MarkupSourceViewerConfiguration;
+import org.eclipse.mylyn.wikitext.ui.editor.ShowInTargetBridge;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.services.IServiceLocator;
+import org.eclipse.ui.swt.IFocusService;
+import org.simantics.views.ViewUtils;
+import org.simantics.views.swt.client.base.SingleSWTViewNode;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class SWTMarkupSourceViewer extends SingleSWTViewNode<StyledText> {
+
+ private static final long serialVersionUID = 3034624586096417826L;
+
+ private MarkupSourceViewer viewer;
+ private boolean textInitialized = false;
+
+ @Override
+ public void createControls(Composite parent) {
+ MarkupLanguage language = new MediaWikiLanguage();
+ viewer = new MarkupSourceViewer(parent, null, style | SWT.WRAP, language);
+ viewer.setEditable(false);
+ MarkupSourceViewerConfiguration configuration = new MarkupSourceViewerConfiguration(Activator.getDefault().getPreferenceStore());
+ configuration.setMarkupLanguage(language);
+ configuration.setShowInTarget(new ShowInTargetBridge(viewer));
+ viewer.configure(configuration);
+ viewer.setDocument(new Document(text != null ? text : ""));
+ control = viewer.getTextWidget();
+ control.setData(TextViewerConstants.KEY_UNDO_MANAGER, viewer.getUndoManager());
+ control.setEnabled(false);
+
+ setProperties();
+
+ // Allow undo/redo handler to be bound to this text editor's focus
+ IServiceLocator locator = getSite();
+ if (locator != null) {
+ IFocusService focusService = locator.getService(IFocusService.class);
+ if (focusService != null) {
+ focusService.addFocusTracker(control, TextViewerConstants.CONTEXT_IN_TEXT_VIEWER);
+ }
+ }
+
+ control.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ ViewUtils.setWorkbenchSelection(viewer.getSelection());
+ }
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+
+ @Override
+ public void synchronizeText(String text) {
+ this.text = text;
+ if (text != null) {
+ // Try to keep the vertical scroll position of the text widget
+ int caretOffset = control.getCaretOffset();
+ int charCount = control.getCharCount();
+ int topIndex = viewer.getTopIndex();
+ int diff = text.length() - charCount;
+ int newCaretOffset = Math.max(0, Math.min(caretOffset + diff, text.length()));
+
+ viewer.getDocument().set(text);
+ viewer.setTopIndex(topIndex);
+ control.setCaretOffset(newCaretOffset);
+ viewer.setEditable(true);
+ control.setEnabled(true);
+
+ // Prevent text viewer undo from allowing the
+ // user to undo the text viewer back to empty.
+ if (!textInitialized) {
+ viewer.getUndoManager().reset();
+ textInitialized = true;
+ }
+ } else {
+ textInitialized = false;
+ viewer.setEditable(false);
+ control.setEnabled(false);
+ viewer.getDocument().set("");
+ viewer.getUndoManager().reset();
+ }
+ }
+
+ public String readText() {
+ return viewer.getDocument().get();
+ }
+
+ public Point readSelection() {
+ return control.getSelection();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - (#7066) initial API and implementation
+ *******************************************************************************/
+package org.simantics.views.text.internal;
+
+import org.eclipse.jface.text.IUndoManager;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.28.0
+ */
+public class TextViewerConstants {
+
+ /**
+ * The UI focus control context used for enabling normal text undo/redo for
+ * {@link TextViewer} controls.
+ */
+ public static final String CONTEXT_IN_TEXT_VIEWER = "inTextViewer";
+
+ /**
+ * A key used for storing an {@link IUndoManager} as data of a
+ * {@link Control} using {@link Control#setData(String, Object)}.
+ */
+ public static final String KEY_UNDO_MANAGER = "undoManager";
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Semantum Oy - (#7066) initial API and implementation
+ *******************************************************************************/
+package org.simantics.views.text.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.jface.text.IUndoManager;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * Handles the undo/redo command for {@link TextViewer}s through
+ * {@link IUndoManager}.
+ *
+ * <p>
+ * The implementation looks for an IUndoManager from the current focus control
+ * using the {@link TextViewerConstants#KEY_UNDO_MANAGER} data key. Its
+ * existence determines whether this handler {@link #isHandled()} returns
+ * <code>true</code> or <code>false</code>.
+ *
+ * <p>
+ * The handler expects to receive a single string as an argument through the
+ * extension definitions ({@link IExecutableExtension}) that determines which
+ * method is invoked from IUndoManager (<code>undo</code> or <code>redo</code>).
+ *
+ * <p>
+ * Implementation is partially copied from
+ * <code>org.eclipse.ui.internal.handlers.WidgetMethodHandler</code>.
+ *
+ * @since 1.28.0
+ */
+public class TextViewerUndoHandler extends AbstractHandler implements IExecutableExtension {
+
+ /**
+ * The parameters to pass to the method this handler invokes. This handler
+ * always passes no parameters.
+ */
+ protected static final Class<?>[] NO_PARAMETERS = new Class[0];
+
+ public TextViewerUndoHandler() {
+ display = Display.getCurrent();
+ if (display != null) {
+ focusListener = new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ updateEnablement();
+ }
+ };
+ display.addFilter(SWT.FocusIn, focusListener);
+ }
+ }
+
+ void updateEnablement() {
+ boolean rc = isHandled();
+ if (rc != isEnabled()) {
+ setBaseEnabled(rc);
+ }
+ }
+
+ /**
+ * The name of the method to be invoked by this handler. This value should
+ * never be <code>null</code>.
+ */
+ protected String methodName;
+ private Listener focusListener;
+ private Display display;
+
+ @Override
+ public Object execute(final ExecutionEvent event) throws ExecutionException {
+ Callable<?> runnable = getMethodToExecute();
+ if (runnable != null) {
+ try {
+ runnable.call();
+ } catch (ExecutionException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ExecutionException("Unexpected failure executing method " + methodName + " through " + runnable);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public final boolean isHandled() {
+ return getMethodToExecute() != null;
+ }
+
+ /**
+ * Looks up the method on the focus control.
+ *
+ * @return The method on the focus control; <code>null</code> if none.
+ */
+ protected Callable<Boolean> getMethodToExecute() {
+ Display display = Display.getCurrent();
+ if (display == null)
+ return null;
+
+ Control focusControl = display.getFocusControl();
+ if (focusControl == null)
+ return null;
+
+ IUndoManager undoManager = (IUndoManager) focusControl.getData(TextViewerConstants.KEY_UNDO_MANAGER);
+ if (undoManager == null)
+ return null;
+
+ try {
+ Method method = undoManager.getClass().getMethod(methodName, NO_PARAMETERS);
+ if (method != null)
+ return runner(undoManager, method);
+ } catch (NoSuchMethodException e) {
+ // Fall through...
+ }
+
+ return null;
+ }
+
+ protected Callable<Boolean> runner(IUndoManager undoManager, Method method) {
+ return () -> {
+ try {
+ method.invoke(undoManager);
+ return true;
+ } catch (IllegalAccessException e) {
+ // The method is protected, so do nothing.
+ return false;
+ } catch (InvocationTargetException e) {
+ throw new ExecutionException(
+ "An exception occurred while executing " //$NON-NLS-1$
+ + method.getName(), e
+ .getTargetException());
+
+ }
+ };
+ }
+
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) {
+ methodName = data.toString();
+ }
+
+ @Override
+ public void dispose() {
+ if (display != null && !display.isDisposed()) {
+ display.removeFilter(SWT.FocusIn, focusListener);
+ }
+ display = null;
+ focusListener = null;
+ }
+
+}
\ No newline at end of file
import com.lowagie.text.pdf.PdfWriter;
public interface IExportable {
- public void export(Document doc, PdfWriter writer) throws DocumentException;
+ /**
+ * @param doc
+ * @param writer
+ * @return the amount of PDF pages exported
+ * @throws DocumentException
+ */
+ public int export(Document doc, PdfWriter writer) throws DocumentException;
}
graph.claim(ontologyName, L0.InstanceOf, null, L0.String);
graph.claimValue(ontologyName, name, WriteBindings.STRING);
graph.claim(ontology, L0.HasName, L0.NameOf, ontologyName);
+ graph.claim(ontology, L0.PartOf, L0.ConsistsOf, parent);
return ontology;
} else {
import org.simantics.graph.db.GraphDependencyAnalyzer.IU;
import org.simantics.graph.db.GraphDependencyAnalyzer.IdentityNode;
import org.simantics.graph.db.IImportAdvisor;
+import org.simantics.graph.db.ImportResult;
import org.simantics.graph.db.TransferableGraphs;
import org.simantics.graph.diff.Diff;
import org.simantics.graph.diff.TransferableGraphDelta1;
import org.simantics.utils.FileUtils;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.logging.TimeLogger;
+import org.simantics.utils.strings.EString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// Install TG
log.log(new Status(IStatus.INFO, Activator.PLUGIN_ID, "Installing "+tg.toString()+" - "+tg.getName()));
- TransferableGraphs.importGraph1(session, new TGTransferableGraphSource(tg.getGraph()), advisor, null);
+ ImportResult result = TransferableGraphs.importGraph1(session, new TGTransferableGraphSource(tg.getGraph()), advisor, null);
+ if (!result.missingExternals.isEmpty()) {
+ log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import of " + tg.toString() + " was missing the following external entities:\n" + EString.implode(result.missingExternals)));
+ }
} else {
// Merge TG
startTransaction(session, false);
<module>org.simantics.views.ontology</module>
<module>org.simantics.views.swt</module>
<module>org.simantics.views.swt.client</module>
+ <module>org.simantics.views.text</module>
+ <module>org.simantics.views.text.ontology</module>
<module>org.simantics.wiki.ui</module>
<module>org.simantics.workbench</module>
<module>org.simantics.workbench.ontology</module>
<?xml version="1.0" encoding="UTF-8"?>
<feature
- id="org.simantics.desktop.product"
+ id="org.simantics.desktop.product.feature"
label="Simantics Desktop Product Feature"
version="1.0.0.qualifier"
provider-name="Semantum Oy">
unpack="false"/>
<plugin
- id="javax.vecmath"
+ id="org.apache.commons.math3"
download-size="0"
install-size="0"
version="0.0.0"
<feature
id="org.simantics.sdk"
label="Simantics SDK"
- version="1.26.0"
+ version="1.29.0"
provider-name="VTT Technical Research Centre of Finland">
<description url="http://www.example.com/description">
id="org.simantics.desktop"
version="0.0.0"/>
+ <includes
+ id="org.simantics.desktop.product.feature"
+ version="0.0.0"/>
+
<plugin
id="org.simantics.fileimport"
download-size="0"
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.eclipse.jetty.http"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jetty.server"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jetty.servlet"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jetty.util"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jetty.io"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.jetty.security"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.ui.cheatsheets"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.servlet"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="org.simantics.views.swt.feature"
- label="SWT views"
+ label="Modelled SWT Views"
version="1.0.1.qualifier"
provider-name="Semantum Oy">
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.simantics.views.text"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.views.text.ontology"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
<module>org.simantics.db.client.feature</module>
<module>org.simantics.db.services.feature</module>
<module>org.simantics.desktop.feature</module>
+ <module>org.simantics.desktop.product.feature</module>
<module>org.simantics.document.base.feature</module>
<module>org.simantics.document.linking.feature</module>
<module>org.simantics.document.swt.feature</module>
#!/bin/bash
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 <major> <minor> <service>"
+ exit -1
+fi
-major=1
-minor=25
-service=0
+major=$1
+minor=$2
+service=$3
ver=${major}.${minor}.${service}
mkdir ${ver}
cd ..
tar zcvf ${ver}.tar.gz ${ver}
rm -rf ${ver}
+
+echo "Packing up mediawiki sites"
+tar zcvf ${ver}-dev-site.tar.gz /var/www/http-dev.simantics.org/
+tar zcvf ${ver}-enduser-site.tar.gz /var/www/https-www.simantics.org/end_user_wiki/
<li><code>simantics.target</code></li>
<li><code>org.simantics.sdk.build.targetdefinition.target</code></li>
</ul>
-<p>At the beginning of simantics.target file, increment <code>sequenceNumber</code> by 1</p>
+<p>At the beginning of simantics.target file, increment <code>sequenceNumber</code> by 1 and replace
+the version numbers in target name and <code>org.simantics.sdk.feature.group</code> and
+<code>org.simantics.sdk.source.feature.group</code> with <code>x.y.z[.w]</code>:</p>
<pre><code><?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
<target name="Simantics x.y.z[.w]" sequenceNumber="11">
+<unit id="org.simantics.sdk.feature.group" version="x.y.z[.w]"/>
+<unit id="org.simantics.sdk.source.feature.group" version="x.y.z[.w]"/>
</code></pre>
<p>Next, replace the following rows in both mentioned files:</p>
<pre><code><repository location="http://www.simantics.org/download/master/sdk"/>
<repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/manual"/>
</code></pre>
</li>
+<li>
+<p>Edit version number of `org.simantics.sdk` feature in `features/org.simantics.sdk.feature/feature.xml` to `x.y.z[.w]`.</p>
+<pre><code>
+<feature
+ id="org.simantics.sdk"
+ label="Simantics SDK"
+ version="x.y.z"
+ provider-name="VTT Technical Research Centre of Finland">
+</code></pre>
+<p>Now commit and push the changes to the release branch.</p>
+</li>
</ol>
<h3>Initialize release branch distribution web site</h3>
<ul>
* `simantics.target`
* `org.simantics.sdk.build.targetdefinition.target`
- At the beginning of simantics.target file, increment `sequenceNumber` by 1
+ At the beginning of simantics.target file, increment `sequenceNumber` by 1 and replace
+ the version numbers in target name and `org.simantics.sdk.feature.group` and
+ `org.simantics.sdk.source.feature.group` with `x.y.z[.w]`:
~~~
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
<target name="Simantics x.y.z[.w]" sequenceNumber="11">
+ <unit id="org.simantics.sdk.feature.group" version="x.y.z[.w]"/>
+ <unit id="org.simantics.sdk.source.feature.group" version="x.y.z[.w]"/>
~~~
Next, replace the following rows in both mentioned files:
<repository location="http://www.simantics.org/download/release/x.y.z[.w]/external-components/manual"/>
~~~
+3. Edit version number of `org.simantics.sdk` feature in `features/org.simantics.sdk.feature/feature.xml` to `x.y.z[.w]`.
+ ~~~
+ <feature
+ id="org.simantics.sdk"
+ label="Simantics SDK"
+ version="x.y.z"
+ provider-name="VTT Technical Research Centre of Finland">
+ ~~~
+
### Initialize release branch distribution web site
* Run [SDK/Deploy External Components to Web](https://www.simantics.org/jenkins/job/SDK/job/Deploy%20External%20Components%20to%20Web/) build with parameters:
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+ <name>org.simantics.desktop.rcp.product</name>\r
+ <comment></comment>\r
+ <projects>\r
+ </projects>\r
+ <buildSpec>\r
+ </buildSpec>\r
+ <natures>\r
+ </natures>\r
+</projectDescription>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.simantics</groupId>
+ <artifactId>org.simantics.desktop.rcp.product</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-repository</packaging>
+
+ <parent>
+ <groupId>org.simantics</groupId>
+ <artifactId>org.simantics.root.releng</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-repository-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <configuration>
+ <includeAllDependencies>true</includeAllDependencies>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-director-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <executions>
+ <execution>
+ <id>materialize-products</id>
+ <goals>
+ <goal>materialize-products</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>archive-products</id>
+ <goals>
+ <goal>archive-products</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>
-<product name="Simantics Desktop" uid="org.simantics.desktop.product.desktopProduct" id="org.simantics.desktop.product.desktopProduct" application="org.simantics.workbench.application" version="1.21.0" useFeatures="true" includeLaunchers="true">
+<product name="Simantics Desktop" uid="Simantics-Desktop" id="org.simantics.desktop.product.desktopProduct" application="org.simantics.workbench.application" version="1.28.0" useFeatures="true" includeLaunchers="true">
<aboutInfo>
<image path="/org.simantics.desktop.ui/icons/simantics256.png"/>
</plugins>
<features>
- <feature id="org.simantics.desktop.product" version="1.0.0.qualifier"/>
+ <feature id="org.simantics.desktop.product.feature" version="1.0.0.qualifier"/>
</features>
<cssInfo>
</cssInfo>
+
+ <configurations>
+ <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="4" />
+ <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.p2.reconciler.dropins" autoStart="true" startLevel="5" />
+ <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
+ </configurations>
</product>
<lucene.version>4.9.0</lucene.version>
<lucene.version.actual>4.9.0.b0003</lucene.version.actual>
<lucene.prefix>org.apache.lucene4</lucene.prefix>
+ <jdom.version>2.0.6</jdom.version>
+ <jdom.version.actual>2.0.6.b0001</jdom.version.actual>
</properties>
</instructions>
</artifact>
<artifact>
- <id>org.jdom:jdom2:2.0.6</id>
+ <id>org.jdom:jdom2:${jdom.version}</id>
<source>true</source>
<instructions>
<Bundle-SymbolicName>org.jdom2</Bundle-SymbolicName>
+ <Bundle-Version>${jdom.version.actual}</Bundle-Version>
+ <Export-Package>*;version="${jdom.version}"</Export-Package>
</instructions>
</artifact>
<artifact>
<Bundle-Version>${itext.version.actual}</Bundle-Version>
</instructions>
</artifact>
- <artifact>
- <id>javax.vecmath:vecmath:1.5.2</id>
- <transitive>false</transitive>
- <override>true</override>
- <instructions>
- <Export-Package>javax.vecmath</Export-Package>
- </instructions>
- </artifact>
<artifact>
<id>org.mozilla:rhino:1.7.7.1</id>
<source>true</source>
</artifact>
<artifact>
- <id>net.java.dev.jna:jna:4.2.2</id>
+ <id>net.java.dev.jna:jna:4.3.0</id>
<source>true</source>
</artifact>
<artifact>
- <id>net.java.dev.jna:jna-platform:4.2.2</id>
+ <id>net.java.dev.jna:jna-platform:4.3.0</id>
<source>true</source>
</artifact>
<artifact>
<unit id="com.koloboke.impl-common-jdk8.source" version="1.0.0"/>
<unit id="com.lowagie.text" version="2.1.7.b1"/>
<unit id="com.lowagie.text.source" version="2.1.7.b1"/>
-<unit id="com.sun.jna" version="4.2.2"/>
-<unit id="com.sun.jna.source" version="4.2.2"/>
-<unit id="com.sun.jna.platform" version="4.2.2"/>
-<unit id="com.sun.jna.platform.source" version="4.2.2"/>
+<unit id="com.sun.jna" version="4.3.0"/>
+<unit id="com.sun.jna.source" version="4.3.0"/>
+<unit id="com.sun.jna.platform" version="4.3.0"/>
+<unit id="com.sun.jna.platform.source" version="4.3.0"/>
<unit id="freemarker" version="2.3.23.stable"/>
<unit id="freemarker.source" version="2.3.23.stable"/>
<unit id="gnu.trove2" version="2.1.0"/>
<unit id="it.unimi.dsi.fastutil" version="7.0.13"/>
<unit id="it.unimi.dsi.fastutil.source" version="7.0.13"/>
<unit id="jakarta-regexp" version="1.4.0"/>
-<unit id="javax.vecmath" version="1.5.2"/>
<unit id="net.jcip.annotations" version="1.0.0"/>
<unit id="net.jcip.annotations.source" version="1.0.0"/>
<unit id="net.ucanaccess" version="3.0.7"/>
<unit id="org.eclipse.collections.eclipse-collections.source" version="7.1.0"/>
<unit id="org.hsqldb.hsqldb" version="2.3.1"/>
<unit id="org.hsqldb.hsqldb.source" version="2.3.1"/>
-<unit id="org.jdom2" version="2.0.6"/>
-<unit id="org.jdom2.source" version="2.0.6"/>
+<unit id="org.jdom2" version="2.0.6.b0001"/>
+<unit id="org.jdom2.source" version="2.0.6.b0001"/>
<unit id="org.jfree.jchart" version="1.0.19"/>
<unit id="org.jfree.jchart.source" version="1.0.19"/>
<unit id="org.jfree.jcommon" version="1.0.23"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
-<target name="Simantics 1.26.0" sequenceNumber="12">
+<target name="Simantics 1.29.0" sequenceNumber="16">
<locations>
<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
-<unit id="org.simantics.sdk.feature.group" version="1.26.0"/>
-<unit id="org.simantics.sdk.source.feature.group" version="1.26.0"/>
+<unit id="org.simantics.sdk.feature.group" version="1.29.0"/>
+<unit id="org.simantics.sdk.source.feature.group" version="1.29.0"/>
<repository location="http://www.simantics.org/download/master/sdk"/>
</location>
<location includeAllPlatforms="true" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
<unit id="com.koloboke.impl-common-jdk8.source" version="1.0.0"/>
<unit id="com.lowagie.text" version="2.1.7.b1"/>
<unit id="com.lowagie.text.source" version="2.1.7.b1"/>
-<unit id="com.sun.jna" version="4.2.2"/>
-<unit id="com.sun.jna.source" version="4.2.2"/>
-<unit id="com.sun.jna.platform" version="4.2.2"/>
-<unit id="com.sun.jna.platform.source" version="4.2.2"/>
+<unit id="com.sun.jna" version="4.3.0"/>
+<unit id="com.sun.jna.source" version="4.3.0"/>
+<unit id="com.sun.jna.platform" version="4.3.0"/>
+<unit id="com.sun.jna.platform.source" version="4.3.0"/>
<unit id="freemarker" version="2.3.23.stable"/>
<unit id="freemarker.source" version="2.3.23.stable"/>
<unit id="gnu.trove2" version="2.1.0"/>
<unit id="it.unimi.dsi.fastutil" version="7.0.13"/>
<unit id="it.unimi.dsi.fastutil.source" version="7.0.13"/>
<unit id="jakarta-regexp" version="1.4.0"/>
-<unit id="javax.vecmath" version="1.5.2"/>
<unit id="net.jcip.annotations" version="1.0.0"/>
<unit id="net.jcip.annotations.source" version="1.0.0"/>
<unit id="net.ucanaccess" version="3.0.7"/>
<unit id="org.eclipse.collections.eclipse-collections.source" version="7.1.0"/>
<unit id="org.hsqldb.hsqldb" version="2.3.1"/>
<unit id="org.hsqldb.hsqldb.source" version="2.3.1"/>
-<unit id="org.jdom2" version="2.0.6"/>
-<unit id="org.jdom2.source" version="2.0.6"/>
+<unit id="org.jdom2" version="2.0.6.b0001"/>
+<unit id="org.jdom2.source" version="2.0.6.b0001"/>
<unit id="org.jfree.jchart" version="1.0.19"/>
<unit id="org.jfree.jchart.source" version="1.0.19"/>
<unit id="org.jfree.jcommon" version="1.0.23"/>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>org.simantics.sdk.repository</artifactId>
- <version>1.26.0-SNAPSHOT</version>
+ <version>1.29.0-SNAPSHOT</version>
<packaging>eclipse-repository</packaging>
<parent>
<modules>
<module>org.simantics.sdk.build.targetdefinition</module>
<module>org.simantics.sdk.repository</module>
+ <module>org.simantics.desktop.rcp.product</module>
</modules>
-</project>
\ No newline at end of file
+</project>
package org.simantics.scl.compiler.tests;
-import org.junit.Test;
-
public class ActiveTests extends TestBase {
public ActiveTests() { super("scl"); }
@Test public void TypeClassBug2() { test(); }
*/
- //@Test public void CityoptSetup() { test(); }
+ //@Test public void Bug6989() { test(); }
- @Test public void Bug6989() { test(); }
}
@Test public void CHR2() { test(); }
@Test public void CHR3() { test(); }
@Test public void CHR4() { test(); }
+ @Test public void ClosureRecursion() { test(); }
@Test public void Collaz() { test(); }
@Test public void Compose() { test(); }
@Test public void Composition() { test(); }
@Test public void FromDynamic4() { test(); }
@Test public void FromDynamic5() { test(); }
@Test public void FunctionFunctor() { test(); }
+ @Test public void FunctionIdentity() { test(); }
@Test public void Functor() { test(); }
@Test public void FunctorM1() { test(); }
@Test public void Generalization() { test(); }
@Test public void LocalDefinitions3() { test(); }
@Test public void LocalDefinitions4() { test(); }
@Test public void LocalDefinitions5() { test(); }
+ @Test public void Logger() { test(); }
@Test public void Macros1() { test(); }
@Test public void Macros2() { test(); }
@Test public void Macros4() { test(); }
@Test public void StringInterpolation3() { test(); }
@Test public void StringMatching1() { test(); }
@Test public void SumOfInverses2() { test(); }
+ @Test public void SwitchSimplification() { test(); }
@Test public void TooManyParametersToSin() { test(); }
@Test public void Transformation1() { test(); }
@Test public void Transformation2() { test(); }
--- /dev/null
+import "Prelude"
+
+countDown :: Ref Integer -> <Proc> Boolean
+countDown r = if currentValue <= 0
+ then False
+ else do
+ r := currentValue - 1
+ True
+ where
+ currentValue = getRef r
+
+strangeLoop :: (<Proc> Boolean) -> <Proc> ()
+strangeLoop cond = if cond
+ then strangeLoop cond
+ else ()
+
+main = do
+ r = ref 100000 :: Ref Integer
+ strangeLoop (countDown r)
+--
+()
\ No newline at end of file
--- /dev/null
+import "Prelude"
+
+f n = do
+ a = n+1
+ \x -> a + x
+
+main = [atan2 1==atan2 1, atan2 1==atan2 2, f 1==f 1, f 1==f 2]
+--
+[true, false, true, false]
\ No newline at end of file
--- /dev/null
+import "Logging"
+
+main = info "Something happened."
+--
+()
\ No newline at end of file
--- /dev/null
+foo () = "asd"
+
+main = foo ()
+--
+asd
\ No newline at end of file