Commit 1fdc6612 authored by Nico Mack's avatar Nico Mack

Implementation of TulipPackage discovery

parent 6f96d1ce
......@@ -180,6 +180,7 @@ TRIANGLE_SIZE_NODE=triangleSize
TRIGGER_CONDITION_NODE=triggerCondition
TRIGGER_ELEMENT=trigger
TRIGGERS_NODE=triggers
TULIP_NAMESPACE=lu.list.itis.dkd.tui
TYPE_NODE=type
UNIT_NODE=unit
UPPER_BOUND_NODE=upperBound
......
......@@ -3,7 +3,7 @@
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId>
<version>2.5.0</version>
<name>TULIP</name>
<name>TULIP Core</name>
<description>A framework for tabletop tangible user interface applications.</description>
<licenses>
......@@ -66,7 +66,10 @@
<implementation-version>${project.version}</implementation-version>
<implementation-build>${buildNumber}</implementation-build>
<build-date>${build.date}</build-date>
</manifestEntries>
</manifestEntries>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
......@@ -82,7 +85,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<version>20.0</version>
</dependency>
<dependency>
<groupId>net.sf.bluecove</groupId>
......@@ -173,6 +176,11 @@
<version>2.1.1e</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
</dependencies>
<repositories>
......
......@@ -69,8 +69,8 @@ public abstract class TangibleApplication {
protected static final Logger LOGGER = LoggerFactory.getLogger(TangibleApplication.class.getSimpleName());
/**
* An instance of the {@link TangibleObjectManager} to handle all interactions with tangible
* objects piloting the interface.
* An instance of the {@link TangibleObjectManager} to handle all interactions with tangible objects
* piloting the interface.
*/
@Nullable
protected TangibleObjectManager objectManager;
......@@ -172,9 +172,9 @@ public abstract class TangibleApplication {
}
/**
* Method used to connect the application to the NUI device sending out events for the listener
* to capture. Before this method can be evoked successfully, the {@link TangibleObjectManager}
* needs to be set.
* Method used to connect the application to the NUI device sending out events for the listener to
* capture. Before this method can be evoked successfully, the {@link TangibleObjectManager} needs
* to be set.
*
* @pre objectManager != <code>null</code>
*
......@@ -185,8 +185,8 @@ public abstract class TangibleApplication {
}
/**
* Method used to disconnect the application from the NUI device sending out events for the
* listener to capture.
* Method used to disconnect the application from the NUI device sending out events for the listener
* to capture.
*
* @pre objectManager != <code>null</code>
*/
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui;
import lu.list.itis.dkd.tui.utility.ManifestReader;
import lu.list.itis.dkd.tui.utility.StringUtils;
import lu.list.itis.dkd.tui.utility.TulipPackage;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class TulipCore implements TulipPackage {
private ManifestReader manifest;
// ***************************************************************************
// * Constants
// ***************************************************************************
private static final String NAME = "Specification-Title"; //$NON-NLS-1$
private static final String BUILD_DATE = "build-date"; //$NON-NLS-1$
private static final String BUILD_NUMBER = "implementation-build"; //$NON-NLS-1$
private static final String VERSION = "implementation-version"; //$NON-NLS-1$
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
*
*/
// ---------------------------------------------------------------------------
public TulipCore() {
manifest = new ManifestReader(this.getClass());
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override
public String getVersion() {
return manifest.getProperty(VERSION);
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override
public String getBuildNumber() {
return manifest.getProperty(BUILD_NUMBER);
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override
public String getBuildDate() {
return manifest.getProperty(BUILD_DATE);
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override
public String getName() {
return manifest.getProperty(NAME);
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override
public String toString() {
return StringUtils.build("{} - {} ({} | {})", getName(), getVersion(), getBuildDate(), getBuildNumber()); //$NON-NLS-1$
}
}
......@@ -215,6 +215,7 @@ public class Externalization extends NLS {
public static String TRIGGER_CONDITION_NODE;
public static String TRIGGER_ELEMENT;
public static String TRIGGERS_NODE;
public static String TULIP_NAMESPACE;
public static String TYPE_NODE;
public static String UNIT_NODE;
public static String UPPER_BOUND_NODE;
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.utility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class ManifestReader {
Attributes attributes;
// ***************************************************************************
// * Constants
// ***************************************************************************
private static final String CLASS_SUFFIX = ".class"; //$NON-NLS-1$
private static final String JAR_PREFIX = "jar"; //$NON-NLS-1$
private static final String FILE_PREFIX = "file"; //$NON-NLS-1$
private static final String TULIP_NAMESPACE = "lu/list/itis/dkd/tui"; //$NON-NLS-1$
private static final String MANIFEST = "/META-INF/MANIFEST.MF"; //$NON-NLS-1$
private static final Logger LOGGER = LoggerFactory.getLogger(ManifestReader.class.getSimpleName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param clazz
*/
// ---------------------------------------------------------------------------
public ManifestReader(Class<?> clazz) {
String className = clazz.getSimpleName() + CLASS_SUFFIX;
String classPath = clazz.getResource(className).toString();
if (classPath.startsWith(JAR_PREFIX)) {
this.readManifestFromJar(classPath);
} else if (classPath.startsWith(FILE_PREFIX)) {
this.readManifestFromFile(classPath);
}
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives
// ***************************************************************************
// ---------------------------------------------------------------------------
private void readManifestFromJar(String classPath) {
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + MANIFEST; //$NON-NLS-1$
this.readManifestFromURL(manifestPath);
}
// ---------------------------------------------------------------------------
private void readManifestFromFile(String classPath) {
String manifestPath = classPath.substring(0, classPath.lastIndexOf(TULIP_NAMESPACE)) + MANIFEST;
this.readManifestFromURL(manifestPath);
}
// ---------------------------------------------------------------------------
private void readManifestFromURL(String url) {
InputStream manifestStream = null;
try {
URL manifestUrl = new URL(url);
manifestStream = manifestUrl.openStream();
Manifest manifest = new Manifest(manifestStream);
this.attributes = manifest.getMainAttributes();
} catch (IOException e) {
LOGGER.error("Error while attempting to access MANIFEST from URL {}", url, e); //$NON-NLS-1$
} finally {
try {
if (manifestStream != null)
manifestStream.close();
} catch (IOException e) {
LOGGER.warn("Failed to close manifest stream!", e); //$NON-NLS-1$
}
}
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param property
* @return
*/
// ---------------------------------------------------------------------------
public String getProperty(String property) {
if (this.attributes != null) {
return this.attributes.getValue(property);
}
return null;
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
// ***************************************************************************
// ---------------------------------------------------------------------------
}
......@@ -23,6 +23,7 @@ import lu.list.itis.dkd.tui.logging.OnScreenLogAppender;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -32,7 +33,10 @@ import java.awt.FontMetrics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
......@@ -57,7 +61,9 @@ public class SplashScreen extends JPanel implements LogListener {
private BufferedImage logo;
private JTextArea log;
private JTextArea about;
private JScrollPane logScroller;
private JScrollPane aboutScroller;
private OnScreenLogAppender appender;
// ***************************************************************************
......@@ -106,6 +112,23 @@ public class SplashScreen extends JPanel implements LogListener {
this.add(logScroller, constraints.xywh(2, 4, 3, 1));
about = new JTextArea();
about.setLineWrap(false);
about.setOpaque(false);
about.setForeground(Color.LIGHT_GRAY);
about.setEditable(false);
about.setColumns(40);
about.setRows(10);
aboutScroller = new JScrollPane(about);
aboutScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
aboutScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
aboutScroller.setAutoscrolls(true);
aboutScroller.setOpaque(false);
aboutScroller.getViewport().setOpaque(false);
this.add(aboutScroller, constraints.xywh(4, 2, 1, 1));
FontMetrics metrics = log.getFontMetrics(log.getFont());
int columns = (int) (screenWidth / (metrics.charWidth('A') * 1.4));
int rows = screenHeight / (2 * metrics.getHeight());
......@@ -115,6 +138,8 @@ public class SplashScreen extends JPanel implements LogListener {
appender = OnScreenLogAppender.getInstance("SplashScreen");
appender.addLogListener(this);
this.findAllTulipPackages();
}
// ---------------------------------------------------------------------------
......@@ -123,6 +148,31 @@ public class SplashScreen extends JPanel implements LogListener {
// ***************************************************************************
// ---------------------------------------------------------------------------
private void findAllTulipPackages() {
Reflections reflections = new Reflections(Externalization.TULIP_NAMESPACE);
Set<Class<? extends TulipPackage>> tulipPackages = reflections.getSubTypesOf(TulipPackage.class);
TulipPackage instance = null;
for (Class<? extends TulipPackage> tulipPackage : tulipPackages) {
Constructor<TulipPackage> constructor;
try {
constructor = (Constructor<TulipPackage>) tulipPackage.getConstructor();
instance = constructor.newInstance();
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
LOGGER.error("Failed to instantiate tulip package {}!", tulipPackage.getSimpleName(), e); //$NON-NLS-1$
}
if (instance != null) {
StringBuilder builder = new StringBuilder(this.about.getText());
builder.append(instance).append("\n");
this.about.setText(builder.toString());
LOGGER.info("Tulip Package: {}", instance); //$NON-NLS-1$
}
}
}
// ---------------------------------------------------------------------------
private BufferedImage getImage(Class<?> referenceClass, String imagePath) {
URL location = referenceClass.getResource(imagePath);
BufferedImage image = null;
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2018. All rights reserved.
*
* This file is part of TULIP.
*
* TULIP is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, version 3 of the
* License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.utility;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public interface TulipPackage {
public String getName();
public String getVersion();
public String getBuildNumber();
public String getBuildDate();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment