Skip to content

Commit

Permalink
plugin api refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
olir committed Apr 7, 2018
1 parent 853df02 commit 3ea3785
Show file tree
Hide file tree
Showing 37 changed files with 283 additions and 292 deletions.
8 changes: 3 additions & 5 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@
</properties>

<parent>
<groupId>de.serviceflow.frankenstein</groupId>
<artifactId>root</artifactId>
<version>0.3.4-SNAPSHOT</version>
<groupId>de.serviceflow.frankenstein</groupId>
<artifactId>root</artifactId>
<version>0.3.4-SNAPSHOT</version>
</parent>

<!-- Maven Coordinates -->
<groupId>de.serviceflow.frankenstein</groupId>
<artifactId>app</artifactId>
<version>0.3.4-SNAPSHOT</version>

<name>Frankenstein - Application</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.List;

import de.serviceflow.frankenstein.Configuration;
import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.SegmentVideoFilter;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
Expand Down Expand Up @@ -52,7 +52,7 @@ public void changed(ObservableValue<? extends SegmentVideoFilter> selected, Segm
String stylesheet = url.toExternalForm();
Scene scene = selectedFilter.createConfigurationScene(stylesheet);
bpContainer.setCenter(scene.getRoot());
SegmentConfigController c = ((SegmentVideoFilter) selectedFilter).getConfigController();
DefaultSegmentConfigController c = ((SegmentVideoFilter) selectedFilter).getConfigController();
c.bind(parent, selectedFilter);
c.fireChange();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import de.serviceflow.frankenstein.ExecutorThread;
import de.serviceflow.frankenstein.MovieProcessor;
import de.serviceflow.frankenstein.ProcessingListener;
import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.SegmentVideoFilter;
import de.serviceflow.frankenstein.vf.FilterElement;
import de.serviceflow.frankenstein.vf.VideoStreamSource;
Expand Down Expand Up @@ -942,7 +942,7 @@ public void run() {
}

@Override
public void configChanged(SegmentConfigController segmentConfigController, SegmentVideoFilter selectedFilter) {
public void configChanged(DefaultSegmentConfigController segmentConfigController, SegmentVideoFilter selectedFilter) {
Runnable r = new Runnable() {
public void run() {
processor.setPreviewFilter(selectedFilter);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.serviceflow.frankenstein.vf.segment;

import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;

public class BWConfigController extends SegmentConfigController {
public class BWConfigController extends DefaultSegmentConfigController {

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import de.serviceflow.frankenstein.plugin.api.DefaultSegmentFilter;
import de.serviceflow.frankenstein.plugin.api.FilterContext;
import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;

public class BWFilter extends DefaultSegmentFilter {

Expand All @@ -47,7 +47,7 @@ protected void initializeController() {
}

@Override
protected SegmentConfigController instantiateController() {
protected DefaultSegmentConfigController instantiateController() {
return new BWConfigController();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package de.serviceflow.frankenstein.vf.segment;

import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;
import javafx.fxml.FXML;
import javafx.scene.control.Slider;

public class StereoDistanceConfigController extends SegmentConfigController {
public class StereoDistanceConfigController extends DefaultSegmentConfigController {

@FXML
Slider sliderStereoPerspective;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import de.serviceflow.frankenstein.plugin.api.DefaultSegmentFilter;
import de.serviceflow.frankenstein.plugin.api.FilterContext;
import de.serviceflow.frankenstein.plugin.api.SegmentConfigController;
import de.serviceflow.frankenstein.plugin.api.DefaultSegmentConfigController;

public class StereoDistanceFilter extends DefaultSegmentFilter {

Expand Down Expand Up @@ -83,7 +83,7 @@ protected void initializeController() {
}

@Override
protected SegmentConfigController instantiateController() {
protected DefaultSegmentConfigController instantiateController() {
return new StereoDistanceConfigController();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

import java.util.Locale;

/**
* Callback to Application Configuration
*/
public interface ConfigManager {
/**
* Current active Locale.
*
* @return Locale object
*/
Locale getLocale();
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
package de.serviceflow.frankenstein.plugin.api;

public class SegmentConfigController {
/**
* Basic controller for FXML Configuration scene of a filter.
*/
public abstract class DefaultSegmentConfigController {

private SegmentFilterConfigListener listener = null;
private SegmentVideoFilter filter = null;

/**
* Bind a SegmentFilterConfigListener and filter to this controller.
* @param l SegmentFilterConfigListener for fireChange() calls.
* @param filter SegmentVideoFilter
*/
public void bind(SegmentFilterConfigListener l, SegmentVideoFilter filter) {
this.listener = l;
this.filter = filter;
}

/**
* Reflect configuration changes to the preview.
*/
public void fireChange() {
if (listener!=null)
listener.configChanged(this, filter);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
/*
* Copyright 2017 Oliver Rode, https://github.com/olir/Frankenstein
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.serviceflow.frankenstein.plugin.api;

import java.io.IOException;
Expand All @@ -24,14 +9,43 @@
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;

/**
* Basic implementation of a SegmentVideoFilter.
*/
public abstract class DefaultSegmentFilter implements SegmentVideoFilter {
private SegmentConfigController configController = null;
private DefaultSegmentConfigController configController = null;

private final String identifier;
private final PropertyResourceBundle bundleConfiguration;
private final String configManagerClass;

/**
* Created an instance for the given IDENTIFIER. Convention is that in the
* package of the implementing class an fxml file of name IDENTIFIER.fxml
* and a property file of name IDENTIFIER.properties (and optionally
* localizations) exists.
*
* The ConfigManager implementation
* de.serviceflow.frankenstein.Configuration is used.
*
* @param identifier
* simple identifier name for this filter.
*/
protected DefaultSegmentFilter(String identifier) {
this(identifier, "de.serviceflow.frankenstein.Configuration");
}

/**
* Like {@link DefaultSegmentFilter#DefaultSegmentFilter(String)}, but with
* the option to specify an individual configManagerClass.
*
* @param identifier simple identifier name for this filter.
* @param configManagerClass
* full qualified class name to a ConfigManager implementation.
*/
protected DefaultSegmentFilter(String identifier, String configManagerClass) {
this.identifier = identifier;
this.configManagerClass = configManagerClass;

bundleConfiguration = (PropertyResourceBundle) ResourceBundle.getBundle(
this.getClass().getPackage().getName().replace('.', '/') + '/' + identifier, getLocale(),
Expand All @@ -45,7 +59,7 @@ private Locale getLocale() {
protected ConfigManager getConfigManager() {
Class<?> fxMain;
try {
fxMain = Class.forName("de.serviceflow.frankenstein.Configuration");
fxMain = Class.forName(configManagerClass);
Class<?> parameterTypes[] = {};
Method main = fxMain.getDeclaredMethod("getInstance", parameterTypes);
Object[] invokeArgs = {};
Expand Down Expand Up @@ -80,16 +94,23 @@ public final Scene createConfigurationScene(String stylesheet) {
}
Scene scene = new Scene(loader.getRoot());
scene.getStylesheets().add(stylesheet);
// configController = loader.getController();
initializeController(); // custom initialization possible here
return scene;
}

abstract protected SegmentConfigController instantiateController();
/**
* Returns, if necessary creates, the controller instance.
*
* @return SegmentConfigController
*/
abstract protected DefaultSegmentConfigController instantiateController();

/**
* initializing the current controller.
*/
abstract protected void initializeController();

public SegmentConfigController getConfigController() {
public DefaultSegmentConfigController getConfigController() {
return configController;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package de.serviceflow.frankenstein.plugin.api;

/**
* Context of filters can be used access context information or to exchange
* data, like results, between different filters in the pipeline.
*/
public interface FilterContext {
Object getValue(String Key);
Object putValue(String Key, Object value);
Object getValue(String key);

Object putValue(String key, Object value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.serviceflow.frankenstein.plugin.api;

/**
* Filter Proxy to JNI Implementation.
*/
public interface JniFilterProxy {
/**
* basic initialization to be implemented native.
*/
void init();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package de.serviceflow.frankenstein.plugin.api;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* Proxy for native JNI calls with the capability to be loaded from external jar
* with methods and callback to load a plug-in-specific native library with base
* name PLUGINNAME. Convention is that the name of the package of the
* implementing class ends with ".plugin.PLUGINNAME".
*/
public abstract class NativeJniProxy {

/**
* Creates new instance and ensured the native library is loaded, by
* preparing it and invoking {@link #loadLibrary(String)}.
*
* @throws UnsatisfiedLinkError if loading the native library failed.
*/
protected NativeJniProxy() throws UnsatisfiedLinkError {
prepareLoadLibrary(this);
}

private void prepareLoadLibrary(NativeJniProxy invoker) throws UnsatisfiedLinkError {
String packageName = invoker.getClass().getPackage().getName();
String pluginName = packageName.substring(packageName.lastIndexOf(".plugin.") + 1);
pluginName = pluginName.substring(0, pluginName.indexOf('.', pluginName.indexOf('.') + 1)).replace('.', '-');

invoker.loadLibrary(prepareLoadLibrary(invoker.getClass(), pluginName));
}

private String prepareLoadLibrary(Class<?> invokerClass, String pluginName) throws UnsatisfiedLinkError {
try {
Class<?> c = invokerClass.getClassLoader().loadClass("de.serviceflow.frankenstein.LibraryManager");
Object o = c.newInstance();
Method m = c.getMethod("prepareLoadLibrary", Class.class, String.class);
return (String) m.invoke(o, invokerClass, pluginName);
} catch (SecurityException | ClassNotFoundException | NoSuchMethodException | InstantiationException
| IllegalAccessException | IllegalArgumentException e) {
e.printStackTrace();
throw new UnsatisfiedLinkError(
"Prepare to load library failed for " + pluginName + " with " + invokerClass.getName());
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t != null)
t.printStackTrace();
e.printStackTrace();
throw new UnsatisfiedLinkError(
"Prepare to load library failed for " + pluginName + " with " + invokerClass.getName());
}
}

/**
* The Implementing class should call "System.loadLibrary(name);" here.
* Remark: The design of Java is to use reflection and internal class loader
* methods.
*
* @param name
* Name of the Library, including base name and architecture.
*/
protected abstract void loadLibrary(String name);
}

0 comments on commit 3ea3785

Please sign in to comment.