├── .gitattributes
├── matconsolectl.png
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── src
├── main
│ ├── resources
│ │ └── matlabcontrol
│ │ │ └── demo
│ │ │ └── logo_128.png
│ └── java
│ │ ├── matlabcontrol
│ │ ├── package-info.java
│ │ ├── extensions
│ │ │ ├── package-info.java
│ │ │ └── MatlabTypeConverter.java
│ │ ├── link
│ │ │ ├── UnsupportedReturnException.java
│ │ │ ├── LinkingException.java
│ │ │ ├── MatlabNonNumericMatrix.java
│ │ │ ├── MatlabInt8.java
│ │ │ ├── MatlabInt32.java
│ │ │ ├── MatlabInt64.java
│ │ │ ├── MatlabInt16.java
│ │ │ ├── MatlabSingle.java
│ │ │ ├── MatlabDouble.java
│ │ │ ├── UnassignableReturnException.java
│ │ │ ├── MatlabLogicalMatrix.java
│ │ │ ├── MatlabLogicalFullMatrix.java
│ │ │ ├── MatlabMatrix.java
│ │ │ ├── MatlabDoubleMatrix.java
│ │ │ ├── LinkedOperations.java
│ │ │ ├── MatlabLogicalSparseMatrix.java
│ │ │ ├── MatlabFunction.java
│ │ │ ├── MatlabInt32Array.java
│ │ │ ├── MatlabInt8Array.java
│ │ │ ├── MatlabInt64Array.java
│ │ │ ├── MatlabInt16Array.java
│ │ │ ├── MatlabSingleArray.java
│ │ │ ├── MatlabDoubleArray.java
│ │ │ ├── MatlabType.java
│ │ │ ├── MatlabNumericMatrix.java
│ │ │ ├── BaseArray.java
│ │ │ ├── ClassInfo.java
│ │ │ ├── MatlabDoubleFullMatrix.java
│ │ │ ├── MatlabVariable.java
│ │ │ ├── MatlabDoubleSparseMatrix.java
│ │ │ ├── MatlabFunctionHandle.java
│ │ │ ├── MatlabReturns.java
│ │ │ └── MatlabNumber.java
│ │ ├── MatlabConnectionException.java
│ │ ├── demo
│ │ │ ├── RemoteMain.java
│ │ │ ├── DemoMain.java
│ │ │ ├── InsideMatlab.java
│ │ │ ├── ArrayPanel.java
│ │ │ ├── ReturnFormatter.java
│ │ │ └── ProxyMethodDescriptor.java
│ │ ├── MatlabSession.java
│ │ ├── RequestReceiver.java
│ │ ├── ProxyFactory.java
│ │ ├── ThrowableWrapper.java
│ │ ├── JMIWrapperRemote.java
│ │ ├── MatlabInvocationException.java
│ │ ├── MatlabSessionImpl.java
│ │ ├── JMIWrapperRemoteImpl.java
│ │ ├── PermissiveSecurityManager.java
│ │ ├── LocalMatlabProxyFactory.java
│ │ ├── LocalHostRMIHelper.java
│ │ ├── LocalMatlabProxy.java
│ │ ├── internal
│ │ │ └── MatlabRMIClassLoaderSpi.java
│ │ ├── MatlabProxyFactory.java
│ │ ├── MatlabBroadcaster.java
│ │ ├── MatlabOperations.java
│ │ ├── MatlabClassLoaderHelper.java
│ │ ├── JMIValidator.java
│ │ └── RemoteMatlabProxy.java
│ │ └── com
│ │ └── mathworks
│ │ └── jmi
│ │ ├── NativeMatlab.java
│ │ └── Matlab.java
└── test
│ └── java
│ └── matlabcontrol
│ ├── CopyPasteTest.java
│ ├── GetAndSetTest.java
│ ├── link
│ └── ArrayUtilsTest.java
│ └── MatlabRequired.java
├── PULL_REQUEST_TEMPLATE.md
├── .github
└── workflows
│ ├── changelog-print.yml
│ ├── gradle-wrapper-validation.yml
│ ├── gradle-build.yml
│ └── deploy.yml
├── gradle.properties
├── settings.gradle
├── LICENSE
├── gradlew.bat
├── CODE_OF_CONDUCT.md
├── CHANGES.md
├── CONTRIBUTING.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.png binary
3 | *.jar binary
4 |
--------------------------------------------------------------------------------
/matconsolectl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diffplug/matconsolectl/HEAD/matconsolectl.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | build/
3 | .gradle/
4 | *.DS_Store
5 |
6 | .project
7 | .classpath
8 | .settings/
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diffplug/matconsolectl/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/src/main/resources/matlabcontrol/demo/logo_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diffplug/matconsolectl/HEAD/src/main/resources/matlabcontrol/demo/logo_128.png
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2015, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/extensions/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2015, DiffPlug
5 | */
6 | package matlabcontrol.extensions;
7 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | After creating the PR, please add a commit that adds a bullet-point under the `-SNAPSHOT` section of [CHANGES.md](https://github.com/diffplug/matconsolectl/blob/master/CHANGES.md) that includes:
2 |
3 | - [ ] a summary of the change
4 | - [ ] a link to the newly created PR
5 |
6 | This makes it easier for the maintainers to quickly release your changes.
7 |
--------------------------------------------------------------------------------
/.github/workflows/changelog-print.yml:
--------------------------------------------------------------------------------
1 | name: changelogPrint
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | name: changelogPrint
9 | steps:
10 | - uses: actions/checkout@v3
11 | - name: jdk 11
12 | uses: actions/setup-java@v3
13 | with:
14 | java-version: 11
15 | distribution: 'temurin'
16 | - name: gradle caching
17 | uses: gradle/gradle-build-action@v2
18 | - run: ./gradlew changelogPrint
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | stable=4.6.0
2 | version=4.7.0-SNAPSHOT
3 | name=matconsolectl
4 | group=com.diffplug.matsim
5 | description=MatConsoleCtl - control MATLAB from Java
6 | org=diffplug
7 |
8 | osgi_manifest_ver=2
9 |
10 | git_url=github.com/diffplug/matconsolectl
11 | maven_group=com.diffplug.matsim
12 | maven_name=matconsolectl
13 | maven_desc=MatConsoleCtl - control MATLAB from Java
14 | javadoc_links=
15 |
16 | license=matconsolectl
17 |
18 | # Build requirements
19 | VER_JAVA=1.6
20 | VER_FINDBUGS=3.0.1
21 |
22 | # Testing
23 | VER_JUNIT=4.12
24 |
--------------------------------------------------------------------------------
/.github/workflows/gradle-wrapper-validation.yml:
--------------------------------------------------------------------------------
1 | name: "Validate Gradle Wrapper"
2 | on:
3 | push:
4 | paths:
5 | - 'gradlew'
6 | - 'gradlew.bat'
7 | - 'gradle/wrapper/'
8 | pull_request:
9 | paths:
10 | - 'gradlew'
11 | - 'gradlew.bat'
12 | - 'gradle/wrapper/'
13 |
14 | permissions:
15 | contents: read
16 |
17 | jobs:
18 | validation:
19 | name: "Validation"
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: actions/checkout@v3
23 | - uses: gradle/wrapper-validation-action@v1
24 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/UnsupportedReturnException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * Thrown if a MATLAB type cannot be returned from MATLAB to Java because it is not supported.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public class UnsupportedReturnException extends RuntimeException {
15 | private static final long serialVersionUID = 0xF500L;
16 |
17 | UnsupportedReturnException(String msg) {
18 | super(msg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/LinkingException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * Issue linking a Java method to a MATLAB function.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public class LinkingException extends RuntimeException {
15 | private static final long serialVersionUID = 0xD500L;
16 |
17 | LinkingException(String msg) {
18 | super(msg);
19 | }
20 |
21 | LinkingException(String msg, Throwable cause) {
22 | super(msg, cause);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/MatlabConnectionException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | /**
9 | * Represents a failure to connect to MATLAB or make MATLAB available for a connection.
10 | *
11 | * @since 2.0.0
12 | *
13 | * @author Joshua Kaplan
14 | */
15 | public class MatlabConnectionException extends Exception {
16 | private static final long serialVersionUID = 0xA400L;
17 |
18 | MatlabConnectionException(String msg) {
19 | super(msg);
20 | }
21 |
22 | MatlabConnectionException(String msg, Throwable cause) {
23 | super(msg, cause);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabNonNumericMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | abstract class MatlabNonNumericMatrix extends MatlabMatrix {
15 | /**
16 | * Returns an array that holds the values from the MATLAB matrix. Each call returns a new copy which may be used in
17 | * any manner; modifications to it will have no effect on this instance.
18 | *
19 | * @return array
20 | */
21 | public T toArray() {
22 | return getBaseArray().toRealArray();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/mathworks/jmi/NativeMatlab.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package com.mathworks.jmi;
7 |
8 | /**
9 | * A partial stubbed out implementation of the NativeMatlab class with the method's used by matlabcontrol. This stub
10 | * exists so that matlabcontrol can compile against this library. At runtime this library is not referenced, instead the
11 | * jmi.jar on MATLAB's classpath is used. The build script for matlabcontrol intentionally does not include this
12 | * library in the distribution folder it generates.
13 | *
14 | * @author Joshua Kaplan
15 | */
16 | public class NativeMatlab {
17 | public static boolean nativeIsMatlabThread() {
18 | throw new UnsupportedOperationException("stub");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabInt8.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code int8} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabInt8 extends MatlabNumber {
15 | private static final Byte DEFAULT = 0;
16 |
17 | public MatlabInt8(byte real, byte imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public byte toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public byte toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabInt32.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code int32} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabInt32 extends MatlabNumber {
15 | private static final Integer DEFAULT = 0;
16 |
17 | public MatlabInt32(int real, int imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public int toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public int toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabInt64.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code int64} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabInt64 extends MatlabNumber {
15 | private static final Long DEFAULT = 0L;
16 |
17 | public MatlabInt64(long real, long imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public long toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public long toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabInt16.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code int16} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabInt16 extends MatlabNumber {
15 | private static final Short DEFAULT = 0;
16 |
17 | public MatlabInt16(short real, short imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public short toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public short toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabSingle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code single} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabSingle extends MatlabNumber {
15 | private static final Float DEFAULT = 0.0f;
16 |
17 | public MatlabSingle(float real, float imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public float toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public float toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabDouble.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * MATLAB {@code double} with real and imaginary components.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | public final class MatlabDouble extends MatlabNumber {
15 | private static final Double DEFAULT = 0.0d;
16 |
17 | public MatlabDouble(double real, double imag) {
18 | super(DEFAULT, real, imag);
19 | }
20 |
21 | /**
22 | * Returns the real value.
23 | *
24 | * @return
25 | */
26 | public double toReal() {
27 | return _real;
28 | }
29 |
30 | /**
31 | * Returns the imaginary value.
32 | *
33 | * @return
34 | */
35 | public double toImaginary() {
36 | return _imag;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/demo/RemoteMain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.demo;
7 |
8 | import java.awt.EventQueue;
9 |
10 | import javax.swing.WindowConstants;
11 |
12 | /**
13 | * Launches the demo when running outside MATLAB.
14 | *
15 | * @author Joshua Kaplan
16 | */
17 | public class RemoteMain {
18 | public static void main(String[] args) {
19 | final String matlabLocation = (args.length == 1 ? args[0] : null);
20 | EventQueue.invokeLater(new Runnable() {
21 | @Override
22 | public void run() {
23 | DemoFrame frame = new DemoFrame("matlabcontrol demo - Running Outside MATLAB", matlabLocation);
24 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
25 | frame.setVisible(true);
26 | }
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/UnassignableReturnException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * The type to be returned is not assignable to the return type. This exception is conceptually similar to a
10 | * {@link ClassCastException} except that it is thrown before the cast would ever occur. For primitive return types,
11 | * this is similar to a {@link NullPointerException} being thrown when the return value is {@code null} and therefore
12 | * cannot be un-boxed.
13 | *
14 | * @since 4.2.0
15 | * @author Joshua Kaplan
16 | */
17 | public class UnassignableReturnException extends RuntimeException {
18 | private static final long serialVersionUID = 0xE500L;
19 |
20 | UnassignableReturnException(String msg) {
21 | super(msg);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/mathworks/jmi/Matlab.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package com.mathworks.jmi;
7 |
8 | /**
9 | * A partial stubbed out implementation of the Matlab class with the method's used by matlabcontrol. This stub exists
10 | * so that matlabcontrol can compile against this library. At runtime this library is not referenced, instead the
11 | * jmi.jar on MATLAB's classpath is used. The build script for matlabcontrol intentionally does not include this
12 | * library in the distribution folder it generates.
13 | *
14 | * @author Joshua Kaplan
15 | */
16 | public class Matlab {
17 | public static Object mtFevalConsoleOutput(String function, Object[] args, int nargout) throws Exception {
18 | throw new UnsupportedOperationException("stub");
19 | }
20 |
21 | public static void whenMatlabIdle(Runnable runnable) {
22 | throw new UnsupportedOperationException("stub");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/MatlabSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.rmi.Remote;
9 | import java.rmi.RemoteException;
10 |
11 | /**
12 | * An implementation of this interface is bound to a RMI registry, representing this session of MATLAB.
13 | *
14 | * @since 4.0.0
15 | *
16 | * @author Joshua Kaplan
17 | */
18 | interface MatlabSession extends Remote {
19 | /**
20 | * Attempts a connection to this session of MATLAB. If this session is available for connection it will send a
21 | * {@link JMIWrapperRemote} to the receiver and {@code true} will be returned. Otherwise {@code false} will be
22 | * returned and no other action will be taken.
23 | *
24 | * @param receiverID
25 | * @param port
26 | * @throws RemoteException
27 | * @return if connection was established
28 | */
29 | public boolean connectFromRMI(String receiverID, int port) throws RemoteException;
30 | }
31 |
--------------------------------------------------------------------------------
/.github/workflows/gradle-build.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 |
6 | # GitHub recommends pinning actions to a commit SHA.
7 | # To get a newer version, you will need to update the SHA.
8 | # You can also reference a tag or branch, but the action may change without warning.
9 |
10 | name: ci
11 |
12 | on: [push]
13 |
14 | jobs:
15 | build:
16 | runs-on: ubuntu-latest
17 | strategy:
18 | matrix:
19 | java: ['11']
20 | name: Java ${{ matrix.java }}
21 | steps:
22 | - uses: actions/checkout@v3
23 | - name: jdk ${{ matrix.java }}
24 | uses: actions/setup-java@v3
25 | with:
26 | java-version: ${{ matrix.java }}
27 | distribution: 'temurin'
28 | - name: git fetch origin main
29 | run: git fetch origin main
30 | - name: gradle wrapper
31 | uses: gradle/wrapper-validation-action@v1
32 | - name: gradle caching
33 | uses: gradle/gradle-build-action@v2
34 | - run: ./gradlew check
35 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | gradlePluginPortal()
5 | }
6 | }
7 | plugins {
8 | // https://github.com/diffplug/blowdryer/blob/main/CHANGELOG.md
9 | id 'com.diffplug.blowdryerSetup' version '1.7.0'
10 | // https://github.com/diffplug/spotless/blob/main/plugin-gradle/CHANGES.md
11 | id 'com.diffplug.spotless' version '6.19.0' apply false
12 | // https://github.com/diffplug/spotless-changelog/blob/main/CHANGELOG.md
13 | id 'com.diffplug.spotless-changelog' version '3.0.2' apply false
14 | // https://plugins.gradle.org/plugin/com.gradle.plugin-publish
15 | id 'com.gradle.plugin-publish' version '1.2.0' apply false
16 | // https://github.com/equodev/equo-ide/blob/main/plugin-gradle/CHANGELOG.md
17 | id 'dev.equo.ide' version '1.3.0' apply false
18 | // https://github.com/gradle-nexus/publish-plugin/releases
19 | id 'io.github.gradle-nexus.publish-plugin' version '1.3.0' apply false
20 | }
21 |
22 | blowdryerSetup {
23 | github 'diffplug/blowdryer-diffplug', 'tag', '7.1.0'
24 | //devLocal '../blowdryer-diffplug'
25 | setPluginsBlockTo {
26 | it.file 'plugin.versions'
27 | }
28 | }
29 |
30 | rootProject.name = 'matlabcontrol'
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabLogicalMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | public abstract class MatlabLogicalMatrix extends MatlabNonNumericMatrix {
14 | MatlabLogicalMatrix() {}
15 |
16 | public static MatlabLogicalMatrix getFull(T values) {
17 | return new MatlabLogicalFullMatrix(values);
18 | }
19 |
20 | public static MatlabLogicalMatrix getSparse(int[] rowIndices, int[] colIndices, boolean[] values,
21 | int numRows, int numCols) {
22 | return new MatlabLogicalSparseMatrix(rowIndices, colIndices, values, numRows, numCols);
23 | }
24 |
25 | public abstract boolean getElementAtLinearIndex(int linearIndex);
26 |
27 | public abstract boolean getElementAtIndices(int row, int column);
28 |
29 | public abstract boolean getElementAtIndices(int row, int column, int page);
30 |
31 | public abstract boolean getElementAtIndices(int row, int column, int[] pages);
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/demo/DemoMain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.demo;
7 |
8 | import java.awt.EventQueue;
9 | import java.net.URL;
10 | import java.net.URLClassLoader;
11 |
12 | import javax.swing.WindowConstants;
13 |
14 | public class DemoMain {
15 | public static void main(String[] args) {
16 | new DemoMain();
17 | }
18 |
19 | public DemoMain() {
20 | final int closeOperation = isRunningInsideMATLAB() ? WindowConstants.HIDE_ON_CLOSE : WindowConstants.EXIT_ON_CLOSE;
21 | EventQueue.invokeLater(new Runnable() {
22 | @Override
23 | public void run() {
24 | DemoFrame frame = new DemoFrame("matlabcontrol demo - Running Inside MATLAB", null);
25 | frame.setDefaultCloseOperation(closeOperation);
26 | frame.setVisible(true);
27 | }
28 | });
29 | }
30 |
31 | private static boolean isRunningInsideMATLAB() {
32 | ClassLoader cl = ClassLoader.getSystemClassLoader();
33 | URL[] urls = ((URLClassLoader) cl).getURLs();
34 | for (URL url : urls) {
35 | if (url.toExternalForm().contains("matlab")) {
36 | return true;
37 | }
38 | }
39 | return false;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabLogicalFullMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | class MatlabLogicalFullMatrix extends MatlabLogicalMatrix {
14 | private final FullArray _array;
15 |
16 | MatlabLogicalFullMatrix(boolean[] values, int[] dimensions) {
17 | _array = new FullArray(boolean[].class, values, null, dimensions);
18 | }
19 |
20 | MatlabLogicalFullMatrix(T values) {
21 | _array = new FullArray(boolean[].class, values, null);
22 | }
23 |
24 | @Override
25 | BaseArray getBaseArray() {
26 | return _array;
27 | }
28 |
29 | @Override
30 | public boolean getElementAtLinearIndex(int linearIndex) {
31 | return _array._real[linearIndex];
32 | }
33 |
34 | @Override
35 | public boolean getElementAtIndices(int row, int column) {
36 | return _array._real[_array.getLinearIndex(row, column)];
37 | }
38 |
39 | @Override
40 | public boolean getElementAtIndices(int row, int column, int page) {
41 | return _array._real[_array.getLinearIndex(row, column, page)];
42 | }
43 |
44 | @Override
45 | public boolean getElementAtIndices(int row, int column, int[] pages) {
46 | return _array._real[_array.getLinearIndex(row, column, pages)];
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | * The base class for all MATLAB matrices.
10 | *
11 | * @since 4.2.0
12 | * @author Joshua Kaplan
13 | */
14 | abstract class MatlabMatrix {
15 | abstract BaseArray getBaseArray();
16 |
17 | /**
18 | * The number of elements in the array. The real and imaginary components of a number are together considered one
19 | * element. This is equivalent to MATLAB's {@code numel} function.
20 | *
21 | * @return number of elements
22 | */
23 | public int getNumberOfElements() {
24 | return getBaseArray().getNumberOfDimensions();
25 | }
26 |
27 | /**
28 | * Returns the length of the dimension specified by {@code dimension}. Dimensions use 0-based indexing. So the
29 | * first dimension, which is dimension 0, is the row length. The second dimension is the column length. The third
30 | * dimension and beyond are pages.
31 | *
32 | * @param dimension
33 | * @return length of {@code dimension}
34 | * @throws IllegalArgumentException if {@code dimension} is not a dimension of the array
35 | */
36 | public int getLengthOfDimension(int dimension) {
37 | return getBaseArray().getLengthOfDimension(dimension);
38 | }
39 |
40 | /**
41 | * Returns the number of dimensions of the array.
42 | *
43 | * @return number of dimensions
44 | */
45 | public int getNumberOfDimensions() {
46 | return getBaseArray().getNumberOfDimensions();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/matlabcontrol/CopyPasteTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import matlabcontrol.MatlabProxyFactory.CopyPasteCallback;
9 |
10 | import org.junit.Assert;
11 | import org.junit.Test;
12 | import org.junit.experimental.categories.Category;
13 |
14 | @Category(MatlabRequired.Interactive.class)
15 | public class CopyPasteTest {
16 | private Runnable runnable;
17 |
18 | @Test
19 | public void testCopyPaste() throws MatlabConnectionException, MatlabInvocationException {
20 | MatlabProxyFactoryOptions.Builder builder = new MatlabProxyFactoryOptions.Builder();
21 | builder.setCopyPasteCallback(new CopyPasteCallback() {
22 | @Override
23 | public void copyPaste(String matlabCmdsToConnect) {
24 | StringBuilder builder = new StringBuilder();
25 | builder.append("Copy-paste the following lines into a MATLAB:\n");
26 | String[] pieces = matlabCmdsToConnect.split(";");
27 | for (String piece : pieces) {
28 | builder.append(" " + piece.trim() + ";\n");
29 | }
30 | builder.append("\nWaiting for you to paste.");
31 | runnable = MatlabRequired.Interactive.prompt(builder.toString());
32 | }
33 | });
34 | MatlabProxyFactory factory = new MatlabProxyFactory(builder.build());
35 | MatlabProxy proxy = factory.getProxy();
36 | try {
37 | runnable.run();
38 | proxy.eval("disp('connection established')");
39 | proxy.setVariable("test", "abc");
40 | Assert.assertEquals("abc", proxy.getVariable("test"));
41 | } finally {
42 | runnable.run();
43 | proxy.disconnect();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | # GH_TOKEN
2 | # NEXUS_USER
3 | # NEXUS_PASS64 (base64 NOTE: `base64` and `openssl base64` failed, had to use Java
4 | # byte[] data = "{{password}}".getBytes(StandardCharsets.UTF_8);
5 | # String encoded = new String(Base64.getEncoder().encode(data), StandardCharsets.UTF_8);
6 | # System.out.println(encoded);
7 | # GPG_PASSPHRASE
8 | # GPG_KEY64 (base64)
9 | # gpg --export-secret-keys --armor KEY_ID | openssl base64 | pbcopy
10 |
11 | name: deploy
12 | on:
13 | workflow_dispatch:
14 | inputs:
15 | to_publish:
16 | description: 'What to publish'
17 | required: true
18 | default: 'all'
19 | type: choice
20 | options:
21 | - all
22 |
23 | jobs:
24 | build:
25 | runs-on: ubuntu-latest
26 | name: deploy
27 | env:
28 | gh_token: ${{ secrets.GH_TOKEN }}
29 | ORG_GRADLE_PROJECT_nexus_user: ${{ secrets.NEXUS_USER }}
30 | ORG_GRADLE_PROJECT_nexus_pass64: ${{ secrets.NEXUS_PASS64 }}
31 | ORG_GRADLE_PROJECT_gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
32 | ORG_GRADLE_PROJECT_gpg_key64: ${{ secrets.GPG_KEY64 }}
33 | steps:
34 | - uses: actions/checkout@v3
35 | - name: jdk 11
36 | uses: actions/setup-java@v3
37 | with:
38 | java-version: 11
39 | distribution: 'temurin'
40 | - name: gradle caching
41 | uses: gradle/gradle-build-action@v2
42 | with:
43 | gradle-home-cache-cleanup: true
44 | - name: git fetch origin main
45 | run: git fetch origin main
46 | - name: publish all
47 | if: "${{ github.event.inputs.to_publish == 'all' }}"
48 | run: |
49 | ./gradlew :changelogPush -Prelease=true -Penable_publishing=true --stacktrace --warning-mode all
50 |
--------------------------------------------------------------------------------
/src/test/java/matlabcontrol/GetAndSetTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import matlabcontrol.link.ArrayUtilsTest;
9 |
10 | import org.junit.AfterClass;
11 | import org.junit.Before;
12 | import org.junit.BeforeClass;
13 | import org.junit.Test;
14 | import org.junit.experimental.categories.Category;
15 |
16 | /**
17 | *
18 | * @author Joshua Kaplan
19 | */
20 | @Category(MatlabRequired.Headless.class)
21 | public class GetAndSetTest {
22 | private static MatlabProxy proxy;
23 |
24 | @BeforeClass
25 | public static void createProxy() throws MatlabConnectionException {
26 | MatlabProxyFactoryOptions.Builder builder = new MatlabProxyFactoryOptions.Builder();
27 | builder.setUsePreviouslyControlledSession(true);
28 | MatlabProxyFactory factory = new MatlabProxyFactory(builder.build());
29 | proxy = factory.getProxy();
30 | }
31 |
32 | @AfterClass
33 | public static void exitMatlab() throws MatlabInvocationException {
34 | if (proxy != null) {
35 | proxy.disconnect();
36 | }
37 | }
38 |
39 | @Before
40 | public void clear() throws MatlabInvocationException {
41 | proxy.eval("clear");
42 | }
43 |
44 | @Test
45 | public void testSetGet() throws MatlabInvocationException {
46 | testCaseSetGet(new boolean[]{true});
47 | testCaseSetGet(new boolean[]{false});
48 |
49 | testCaseSetGet(new double[]{1.5});
50 |
51 | testCaseSetGet("string");
52 | }
53 |
54 | private void testCaseSetGet(Object set) throws MatlabInvocationException {
55 | proxy.setVariable("a", set);
56 | Object get = proxy.getVariable("a");
57 | ArrayUtilsTest.assertArraysEqual(set, get);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/RequestReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.rmi.Remote;
9 | import java.rmi.RemoteException;
10 |
11 | /**
12 | * Represents a receiver for a request to create a proxy. The receiver must be bound to an RMI registry, it will be
13 | * bound with the RMI identifier {@link #getReceiverID()}. Necessary to have this interface for RMI.
14 | *
15 | * @since 4.0.0
16 | *
17 | * @author Joshua Kaplan
18 | */
19 | interface RequestReceiver extends Remote {
20 | /**
21 | * Receives an incoming wrapper around the JMI functionality inside of MATLAB.
22 | *
23 | * This method is to be called by {@link MatlabConnector} running inside of MATLAB's JVM.
24 | *
25 | * @param jmiWrapper
26 | * @param existingSession if the session sending the jmiWrapper was running prior to the request to create the proxy
27 | * @throws RemoteException
28 | */
29 | public void receiveJMIWrapper(JMIWrapperRemote jmiWrapper, boolean existingSession) throws RemoteException;
30 |
31 | /**
32 | * The identifier of the receiver.
33 | *
34 | * @return
35 | * @throws RemoteException
36 | */
37 | public String getReceiverID() throws RemoteException;
38 |
39 | /**
40 | * The classpath of the VM the receiver was created in encoded as an RMI codebase.
41 | *
42 | * @return
43 | * @throws RemoteException
44 | */
45 | public String getClassPathAsRMICodebase() throws RemoteException;
46 |
47 | /**
48 | * The classpath of the VM the receiver was created in encoded as canonical paths.
49 | *
50 | * @return
51 | * @throws RemoteException
52 | */
53 | public String[] getClassPathAsCanonicalPaths() throws RemoteException;
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/ProxyFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import matlabcontrol.MatlabProxyFactory.Request;
9 | import matlabcontrol.MatlabProxyFactory.RequestCallback;
10 |
11 | /**
12 | * A factory which creates instances of {@link MatlabProxy}.
13 | *
14 | * @since 4.0.0
15 | *
16 | * @author Joshua Kaplan
17 | */
18 | interface ProxyFactory {
19 | /**
20 | * Returns a {@link MatlabProxy}. If a connection cannot be established before the timeout then this method will end
21 | * execution and an exception will be thrown. A timeout can be specified with the options provided to this factory.
22 | * If no timeout was specified, then a default of 180 seconds will be used.
23 | *
24 | * While this method blocks the calling thread until a proxy is created (or the timeout is reached), any number of
25 | * threads may call {@code getProxy()} simultaneously.
26 | *
27 | * @throws MatlabConnectionException
28 | * @return proxy
29 | */
30 | public MatlabProxy getProxy() throws MatlabConnectionException;
31 |
32 | /**
33 | * Requests a {@link MatlabProxy}. When the proxy has been created it will be provided to the {@code callback}. The
34 | * proxy may be provided to the callback before this method returns. There is no timeout. The returned
35 | * {@link Request} instance provides information about the request and can be used to cancel the request.
36 | *
37 | * This method is non-blocking. Any number of requests may be made simultaneously from the same thread or different
38 | * threads.
39 | *
40 | * @throws MatlabConnectionException
41 | * @return request
42 | */
43 | public Request requestProxy(RequestCallback callback) throws MatlabConnectionException;
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/demo/InsideMatlab.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.demo;
7 |
8 | import java.awt.EventQueue;
9 | import java.net.URL;
10 | import java.net.URLClassLoader;
11 |
12 | import javax.swing.WindowConstants;
13 |
14 | /**
15 | * This class exists solely as a entry point to the demo when running it from inside of MATLAB. By placing it in the
16 | * default package and giving it the name that it has, it means that once the code is added to MATLAB's Java classpath
17 | * then the demo can be launched just by typing {@code matlabcontroldemo}. Typing that will cause the constructor of
18 | * this class to be called.
19 | *
20 | * @author Joshua Kaplan
21 | */
22 | class InsideMatlab {
23 | public static void main(String[] args) {
24 | ClassLoader cl = ClassLoader.getSystemClassLoader();
25 | URL[] urls = ((URLClassLoader) cl).getURLs();
26 | for (URL url : urls) {
27 | System.out.println(url.getFile());
28 | }
29 |
30 | EventQueue.invokeLater(new Runnable() {
31 | @Override
32 | public void run() {
33 | DemoFrame frame = new DemoFrame("matlabcontrol demo - Running Inside MATLAB", null);
34 | frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
35 | frame.setVisible(true);
36 | }
37 | });
38 | }
39 |
40 | /**
41 | * This method will be called by MATLAB to provide the text for the {@code ans} value. By overriding this method
42 | * in this manner it will cause this method's return value to be used as a status message:
43 | *
52 | *
53 | * @return
54 | */
55 | @Override
56 | public String toString() {
57 | return "matlabcontrol demo launching...";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabDoubleMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | public abstract class MatlabDoubleMatrix extends MatlabNumericMatrix {
14 | MatlabDoubleMatrix() {}
15 |
16 | public static MatlabDoubleMatrix getFull(T real, T imag) {
17 | return new MatlabDoubleFullMatrix(real, imag);
18 | }
19 |
20 | public static MatlabDoubleMatrix getSparse(int[] rowIndices, int[] colIndices,
21 | double[] real, double[] imag, int numRows, int numCols) {
22 | return new MatlabDoubleSparseMatrix(rowIndices, colIndices, real, imag, numRows, numCols);
23 | }
24 |
25 | public abstract double getRealElementAtLinearIndex(int linearIndex);
26 |
27 | public abstract double getImaginaryElementAtLinearIndex(int linearIndex);
28 |
29 | public abstract double getRealElementAtIndices(int row, int column);
30 |
31 | public abstract double getRealElementAtIndices(int row, int column, int page);
32 |
33 | public abstract double getRealElementAtIndices(int row, int column, int[] pages);
34 |
35 | public abstract double getImaginaryElementAtIndices(int row, int column);
36 |
37 | public abstract double getImaginaryElementAtIndices(int row, int column, int page);
38 |
39 | public abstract double getImaginaryElementAtIndices(int row, int column, int[] pages);
40 |
41 | @Override
42 | public abstract MatlabDouble getElementAtLinearIndex(int linearIndex);
43 |
44 | @Override
45 | public abstract MatlabDouble getElementAtIndices(int row, int column);
46 |
47 | @Override
48 | public abstract MatlabDouble getElementAtIndices(int row, int column, int page);
49 |
50 | @Override
51 | public abstract MatlabDouble getElementAtIndices(int row, int column, int... pages);
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/LinkedOperations.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | import matlabcontrol.MatlabInvocationException;
9 | import matlabcontrol.MatlabOperations;
10 | import matlabcontrol.MatlabProxy;
11 |
12 | /**
13 | *
14 | * @since 4.2.0
15 | * @author Joshua Kaplan
16 | */
17 | public final class LinkedOperations implements MatlabOperations {
18 | private final MatlabProxy _delegateProxy;
19 | private final MatlabOperations _delegateOperations;
20 |
21 | public LinkedOperations(MatlabProxy proxy) {
22 | _delegateProxy = proxy;
23 | _delegateOperations = Linker.getLinkedMatlabOperations(proxy);
24 | }
25 |
26 | @Override
27 | public void eval(String command) throws MatlabInvocationException {
28 | _delegateOperations.eval(command);
29 | }
30 |
31 | @Override
32 | public Object[] returningEval(String command, int nargout) throws MatlabInvocationException {
33 | return _delegateOperations.returningEval(command, nargout);
34 | }
35 |
36 | @Override
37 | public void feval(String functionName, Object... args) throws MatlabInvocationException {
38 | _delegateOperations.feval(functionName, args);
39 | }
40 |
41 | @Override
42 | public Object[] returningFeval(String functionName, int nargout, Object... args) throws MatlabInvocationException {
43 | return _delegateOperations.returningFeval(functionName, nargout, args);
44 | }
45 |
46 | @Override
47 | public void setVariable(String variableName, Object value) throws MatlabInvocationException {
48 | _delegateOperations.setVariable(variableName, value);
49 | }
50 |
51 | @Override
52 | public Object getVariable(String variableName) throws MatlabInvocationException {
53 | return _delegateOperations.getVariable(variableName);
54 | }
55 |
56 | /**
57 | * The proxy used to communicate with MATLAB.
58 | *
59 | * @return proxy
60 | */
61 | public MatlabProxy getDelegateProxy() {
62 | return _delegateProxy;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabLogicalSparseMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | class MatlabLogicalSparseMatrix extends MatlabLogicalMatrix {
14 | private final SparseArray _array;
15 |
16 | MatlabLogicalSparseMatrix(int[] linearIndices, int[] rowIndices, int[] colIndices, boolean[] values,
17 | int numRows, int numCols) {
18 | _array = new SparseArray(boolean[].class, linearIndices, rowIndices, colIndices, values, null,
19 | numRows, numCols);
20 | }
21 |
22 | MatlabLogicalSparseMatrix(int[] rowIndices, int[] colIndices, boolean[] values, int numRows, int numCols) {
23 | _array = new SparseArray(boolean[].class, rowIndices, colIndices, values, null, numRows, numCols);
24 | }
25 |
26 | @Override
27 | BaseArray getBaseArray() {
28 | return _array;
29 | }
30 |
31 | private boolean getElementAtSparseIndex(int sparseIndex) {
32 | boolean val = false;
33 | if (sparseIndex >= 0) {
34 | val = _array._realValues[sparseIndex];
35 | }
36 |
37 | return val;
38 | }
39 |
40 | @Override
41 | public boolean getElementAtLinearIndex(int linearIndex) {
42 | return getElementAtSparseIndex(_array.getSparseIndexForLinearIndex(linearIndex));
43 | }
44 |
45 | @Override
46 | public boolean getElementAtIndices(int row, int column) {
47 | return getElementAtSparseIndex(_array.getSparseIndexForIndices(row, column));
48 | }
49 |
50 | @Override
51 | public boolean getElementAtIndices(int row, int column, int page) {
52 | throw new IllegalArgumentException("Array has 2 dimensions, it cannot be indexed into using 3 indices");
53 | }
54 |
55 | @Override
56 | public boolean getElementAtIndices(int row, int column, int[] pages) {
57 | throw new IllegalArgumentException("Array has 2 dimensions, it cannot be indexed into using " +
58 | (2 + pages.length) + " indices");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/ThrowableWrapper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | /**
9 | * A wrapper around any {@link Throwable} so that it can be sent over RMI without needing the class to be defined in
10 | * the receiving JVM. The stack trace will print as if it were the original throwable.
11 | *
12 | * @since 4.0.0
13 | *
14 | * @author Joshua Kaplan
15 | */
16 | class ThrowableWrapper extends Throwable {
17 | private static final long serialVersionUID = 0xC500L;
18 |
19 | /**
20 | * The {@code String} representation of the {@code MatlabException} so that this exception can pretend to be a
21 | * {@code MatlabException}.
22 | */
23 | private final String _toString;
24 |
25 | /**
26 | * Creates a wrapper around {@code innerThrowable} so that when the stack trace is printed it is the same to the
27 | * developer, but can be sent over RMI without the throwable being defined in the other JVM.
28 | *
29 | * @param innerThrowable
30 | */
31 | ThrowableWrapper(Throwable innerThrowable) {
32 | super(msgFromToString(innerThrowable));
33 | //Store innerThrowable's toString() value
34 | _toString = innerThrowable.toString();
35 |
36 | //Set this stack trace to that of the innerThrowable
37 | this.setStackTrace(innerThrowable.getStackTrace());
38 |
39 | //Store the cause, wrapping it
40 | if (innerThrowable.getCause() != null) {
41 | this.initCause(new ThrowableWrapper(innerThrowable.getCause()));
42 | }
43 | }
44 |
45 | /**
46 | * The innerThrowable seems to not implement getMessage() properly.
47 | *
48 | * So we extract the message from the exception's toString() method.
49 | */
50 | static String msgFromToString(Throwable e) {
51 | String msg = e.toString();
52 | int idx = msg.indexOf(':');
53 | if (idx >= 0 && idx < msg.length() - 1) {
54 | return msg.substring(idx + 1);
55 | } else {
56 | return msg;
57 | }
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return _toString;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | /**
14 | * Information about a MATLAB function.
15 | *
16 | * @since 4.2.0
17 | * @author Joshua Kaplan
18 | */
19 | @Retention(RetentionPolicy.RUNTIME)
20 | @Target(ElementType.METHOD)
21 | public @interface MatlabFunction {
22 | /**
23 | * Either the name of a MATLAB function or a path to a MATLAB function. The value provided to this element is
24 | * resolved in the following order:
25 | *
26 | *
Valid MATLAB function name
27 | * The value will be treated as a function on MATLAB's path. Whether a function with the specified name is
28 | * actually on MATLAB's path will not be confirmed.
29 | *
Absolute path to an m-file
30 | * The value will be treated as the location of an m-file. The file's existence will be confirmed.
31 | *
Relative path to an m-file
32 | * The value will be treated as the location of an m-file relative to the root directory of the interface which
33 | * declared the method being annotated. For example if the interface is {@code com.example.MyInterface} located
34 | * at {@code /projects/code/numera/com/example/MyInterface.java} then path will be resolved relative to
35 | * {@code /projects/code/numera/}. This path can be resolved properly when both the interface and m-file are
36 | * inside of a zip file such as a jar or war file. The file's existence will be confirmed.
37 | *
38 | * The validity of this element's value will be determined when the interface containing the method being annotated
39 | * is provided to {@link MatlabFunctionLinker#link(java.lang.Class, matlabcontrol.MatlabProxy)}.
40 | *
41 | * @return
42 | */
43 | String value();
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/JMIWrapperRemote.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.rmi.Remote;
9 | import java.rmi.RemoteException;
10 |
11 | /**
12 | * Methods that can be called to control MATLAB except for {@link #checkConnection()}.
13 | *
14 | * All of these methods throw RemoteException. RemoteException will be thrown if something occurs to disrupt the
15 | * communication between this JVM and the one MATLAB is running in. For instance, closing MATLAB will terminate its
16 | * JVM and then all method calls on this proxy will throw exceptions.
17 | *
13 | * Methods called on this proxy will be performed inside of the JVM that created this object. This class is only created
14 | * inside of the MATLAB's JVM and so {@code JMIWrapper}'s calls will be able to communicate with MATLAB.
15 | *
16 | * These methods are documented in {@link MatlabProxy}.
17 | *
18 | * @since 4.0.0
19 | *
20 | * @author Joshua Kaplan
21 | */
22 | class JMIWrapperRemoteImpl extends LocalHostRMIHelper.LocalHostRemoteObject implements JMIWrapperRemote {
23 | private static final long serialVersionUID = 6263244863419922018L;
24 |
25 | public JMIWrapperRemoteImpl() throws RemoteException {}
26 |
27 | @Override
28 | public void exit() {
29 | JMIWrapper.exit();
30 | }
31 |
32 | @Override
33 | public void eval(String command) throws MatlabInvocationException {
34 | JMIWrapper.eval(command);
35 | }
36 |
37 | @Override
38 | public Object[] returningEval(String command, int nargout) throws MatlabInvocationException {
39 | return JMIWrapper.returningEval(command, nargout);
40 | }
41 |
42 | @Override
43 | public void feval(String command, Object... args) throws MatlabInvocationException {
44 | JMIWrapper.feval(command, args);
45 | }
46 |
47 | @Override
48 | public Object[] returningFeval(String command, int nargout, Object... args) throws MatlabInvocationException {
49 | return JMIWrapper.returningFeval(command, nargout, args);
50 | }
51 |
52 | @Override
53 | public void setVariable(String variableName, Object value) throws MatlabInvocationException {
54 | JMIWrapper.setVariable(variableName, value);
55 | }
56 |
57 | @Override
58 | public Object getVariable(String variableName) throws MatlabInvocationException {
59 | return JMIWrapper.getVariable(variableName);
60 | }
61 |
62 | @Override
63 | public T invokeAndWait(MatlabProxy.MatlabThreadCallable callable) throws MatlabInvocationException {
64 | return JMIWrapper.invokeAndWait(callable);
65 | }
66 |
67 | @Override
68 | public void checkConnection() {}
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/PermissiveSecurityManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.security.Permission;
9 |
10 | /**
11 | * A {@code SecurityManager} that always permits an action to take place. By default a Java application has no
12 | * {@code SecurityManager} set (although Java applets do). This security manager acts as if there was no security
13 | * manager in place. matlabcontrol uses Remote Method Invocation (RMI) to communicate with MATLAB when it is used in an
14 | * application that is not running inside MATLAB. RMI requires a security manager be set in order to allow loading
15 | * classes that are defined in the other Java Virtual Machine, but not its own. This is for good reason, because
16 | * allowing arbitrary code to be loaded into an application has the potential for a security exploit. By default RMI
17 | * allows connections from any external machine unless otherwise configured (or blocked by a firewall). matlabcontrol
18 | * is configured to prohibit any external connections on the port it is using.
19 | *
20 | * When matlabcontrol launches a session of MATLAB it installs this security manager so that MATLAB may load classes
21 | * defined in your application. matlabcontrol does not install this security manager in your program. Installing any
22 | * security manager will allow your application to receive objects from MATLAB that are of classes defined in MATLAB,
23 | * but not in your application. Using this security manager is convenient when your application does not need any
24 | * security beyond the default of having no security manager installed.
25 | *
16 | * Subclasses of this either final or abstract and non-extenable with final subclasses of their own. Being final makes
17 | * it easier to ensure appropriate behavior when transforming types automatically. Subclasses are not
18 | * {@link Serializable} to reduce the publicly exposed API and reduce the need to maintain serializable compatibility.
19 | * Instead, transferring occurs by use of {@link MatlabTypeSetter} and {@link MatlabTypeGetter}. A getter is typically
20 | * associated with a class as an inner static class.
21 | *
22 | * @since 4.2.0
23 | * @author Joshua Kaplan
24 | */
25 | abstract class MatlabType {
26 | MatlabType() {}
27 |
28 | abstract MatlabTypeSetter getSetter();
29 |
30 | /**
31 | * Retrieves in MATLAB the information necessary to create the associated {@code MatlabType} from a given MATLAB
32 | * variable.
33 | *
34 | * Must have an accessible no argument constructor.
35 | *
36 | * @param
37 | */
38 | static interface MatlabTypeGetter extends Serializable {
39 | /**
40 | * Takes the information retrieved by the
41 | * {@link #getInMatlab(matlabcontrol.MatlabOperations, java.lang.String)} and creates the
42 | * associated {@code MatlabType}.
43 | *
44 | * @return
45 | */
46 | public T retrieve();
47 |
48 | /**
49 | * Retrieves the data it needs from the variable in MATLAB. So that after retrieving this information
50 | * {@link #retrieve()} can be called to create the appropriate {@code MatlabType}.
51 | *
52 | * @param ops
53 | * @param variableName
54 | */
55 | public void getInMatlab(MatlabOperations ops, String variableName) throws MatlabInvocationException;
56 | }
57 |
58 | /**
59 | * Sets in MATLAB the equivalent of the data represented by the {@code MatlabType} that provides an instance of
60 | * an implementation of this class.
61 | */
62 | static interface MatlabTypeSetter extends Serializable {
63 | public void setInMatlab(MatlabOperations ops, String variableName) throws MatlabInvocationException;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/LocalMatlabProxyFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.util.concurrent.atomic.AtomicInteger;
9 |
10 | import matlabcontrol.MatlabProxy.Identifier;
11 | import matlabcontrol.MatlabProxyFactory.Request;
12 | import matlabcontrol.MatlabProxyFactory.RequestCallback;
13 |
14 | /**
15 | * Creates local instances of {@link MatlabProxy}.
16 | *
17 | * @since 4.0.0
18 | *
19 | * @author Joshua Kaplan
20 | */
21 | class LocalMatlabProxyFactory implements ProxyFactory {
22 | public LocalMatlabProxyFactory(MatlabProxyFactoryOptions options) {}
23 |
24 | @Override
25 | public LocalMatlabProxy getProxy() throws MatlabConnectionException {
26 | JMIValidator.validateJMIMethods();
27 |
28 | return new LocalMatlabProxy(new LocalIdentifier());
29 | }
30 |
31 | @Override
32 | public Request requestProxy(RequestCallback requestCallback) throws MatlabConnectionException {
33 | LocalMatlabProxy proxy = getProxy();
34 | requestCallback.proxyCreated(proxy);
35 |
36 | return new LocalRequest(proxy.getIdentifier());
37 | }
38 |
39 | private static final class LocalIdentifier implements Identifier {
40 | private static final AtomicInteger PROXY_CREATION_COUNTER = new AtomicInteger();
41 |
42 | private final int _id = PROXY_CREATION_COUNTER.getAndIncrement();
43 |
44 | @Override
45 | public boolean equals(Object other) {
46 | boolean equals;
47 |
48 | if (other instanceof LocalIdentifier) {
49 | equals = (((LocalIdentifier) other)._id == _id);
50 | } else {
51 | equals = false;
52 | }
53 |
54 | return equals;
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 | return _id;
60 | }
61 |
62 | @Override
63 | public String toString() {
64 | return "PROXY_LOCAL_" + _id;
65 | }
66 | }
67 |
68 | private static final class LocalRequest implements Request {
69 | private final Identifier _proxyID;
70 |
71 | private LocalRequest(Identifier proxyID) {
72 | _proxyID = proxyID;
73 | }
74 |
75 | @Override
76 | public Identifier getProxyIdentifer() {
77 | return _proxyID;
78 | }
79 |
80 | @Override
81 | public boolean cancel() {
82 | return false;
83 | }
84 |
85 | @Override
86 | public boolean isCancelled() {
87 | return false;
88 | }
89 |
90 | @Override
91 | public boolean isCompleted() {
92 | return true;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabNumericMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | abstract class MatlabNumericMatrix extends MatlabMatrix {
14 | /**
15 | * Returns {@code true} if the array has no imaginary values, {@code false} otherwise. Equivalent to the MATLAB
16 | * {@code isreal} function.
17 | *
18 | * @return
19 | */
20 | public boolean isReal() {
21 | return getBaseArray().isReal();
22 | }
23 |
24 | /**
25 | * Returns an array that holds the real values from the MATLAB array. Each call returns a new copy which may be used
26 | * in any manner; modifications to it will have no effect on this instance.
27 | *
28 | * @return real array
29 | */
30 | public T toRealArray() {
31 | return getBaseArray().toRealArray();
32 | }
33 |
34 | /**
35 | * Returns an array that holds the imaginary values from the MATLAB array. Each call returns a new copy which may be
36 | * used in any manner; modifications to it will have no effect on this instance. If this array is real then the
37 | * returned array will be have {@code 0} as all of its base elements.
38 | *
39 | * @return imaginary array
40 | */
41 | public T toImaginaryArray() {
42 | return getBaseArray().toImaginaryArray();
43 | }
44 |
45 | /**
46 | * Gets the element at {@code index} treating this array as a MATLAB column vector. This is equivalent to indexing
47 | * into a MATLAB array with just one subscript.
48 | *
49 | * @param index
50 | * @return element at {@code index}
51 | * @throws ArrayIndexOutOfBoundsException if {@code index} is out of bounds
52 | */
53 | public abstract MatlabNumber> getElementAtLinearIndex(int index);
54 |
55 | public abstract MatlabNumber> getElementAtIndices(int row, int column);
56 |
57 | public abstract MatlabNumber> getElementAtIndices(int row, int column, int page);
58 |
59 | /**
60 | * Gets the element at the specified {@code row}, {@code column}, and {@code pages}.
61 | *
62 | * @param row
63 | * @param column
64 | * @param pages
65 | * @return element at {@code row}, {@code column}, and {@code pages}
66 | * @throws IllegalArgumentException if number of indices does not equal this array's number of dimensions
67 | * @throws ArrayIndexOutOfBoundsException if the indices are out of bound
68 | */
69 | public abstract MatlabNumber> getElementAtIndices(int row, int column, int... pages);
70 | }
71 |
--------------------------------------------------------------------------------
/src/test/java/matlabcontrol/link/ArrayUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | import org.junit.Assert;
9 | import org.junit.ComparisonFailure;
10 | import org.junit.Test;
11 |
12 | public class ArrayUtilsTest {
13 | @Test
14 | public void testDeepCopyOnPrimitives() {
15 | byte[] bytes = new byte[]{1, 2, 3, 4, 5};
16 | byte[] bytesCopied = ArrayUtils.deepCopy(bytes);
17 | Assert.assertTrue(bytes != bytesCopied);
18 | Assert.assertArrayEquals(bytes, bytesCopied);
19 |
20 | short[] shorts = new short[]{1, 2, 3, 4, 5};
21 | short[] shortsCopied = ArrayUtils.deepCopy(shorts);
22 | Assert.assertTrue(shorts != shortsCopied);
23 | Assert.assertArrayEquals(shorts, shortsCopied);
24 |
25 | int[] ints = new int[]{1, 2, 3, 4, 5};
26 | int[] intsCopied = ArrayUtils.deepCopy(ints);
27 | Assert.assertTrue(ints != intsCopied);
28 | Assert.assertArrayEquals(ints, intsCopied);
29 |
30 | long[] longs = new long[]{1, 2, 3, 4, 5};
31 | long[] longsCopied = ArrayUtils.deepCopy(longs);
32 | Assert.assertTrue(longs != longsCopied);
33 | Assert.assertArrayEquals(longs, longsCopied);
34 |
35 | float[] floats = new float[]{1, 2, 3, 4, 5};
36 | float[] floatsCopied = ArrayUtils.deepCopy(floats);
37 | Assert.assertTrue(floats != floatsCopied);
38 | Assert.assertArrayEquals(floats, floatsCopied, 0.01f);
39 |
40 | double[] doubles = new double[]{1, 2, 3, 4, 5};
41 | double[] doublesCopied = ArrayUtils.deepCopy(doubles);
42 | Assert.assertTrue(doubles != doublesCopied);
43 | Assert.assertArrayEquals(doubles, doublesCopied, 0.01);
44 |
45 | boolean[] bools = new boolean[]{true, true, false, true};
46 | boolean[] boolsCopied = ArrayUtils.deepCopy(bools);
47 | Assert.assertTrue(bools != boolsCopied);
48 | Assert.assertArrayEquals(bools, boolsCopied);
49 |
50 | char[] chars = new char[]{1, 2, 3, 4, 5};
51 | char[] charsCopied = ArrayUtils.deepCopy(chars);
52 | Assert.assertTrue(chars != charsCopied);
53 | Assert.assertArrayEquals(chars, charsCopied);
54 | }
55 |
56 | public static void assertArraysEqual(Object expected, Object actual) {
57 | if (expected.getClass().isArray()) {
58 | if (!ArrayUtils.equals(expected, actual)) {
59 | throw new ComparisonFailure("test failed", toString(expected), toString(actual));
60 | }
61 | } else {
62 | if (!expected.equals(actual)) {
63 | throw new ComparisonFailure("test failed", toString(expected), toString(actual));
64 | }
65 | }
66 | }
67 |
68 | private static String toString(Object any) {
69 | return "class: " + any.getClass() + "\ntoString: " + any.toString();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/BaseArray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 | *
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | *
13 | * @param underlying linear array - single dimensional array type, ex. {@code byte[]}
14 | * @param output array - primitive numeric array type, ex. {@code byte[][][]}
15 | * (1 or more dimensions is acceptable, including for example {@code byte[]})
16 | */
17 | abstract class BaseArray {
18 | /**
19 | * Returns {@code true} if the array has no imaginary values, {@code false} otherwise. Equivalent to the MATLAB
20 | * {@code isreal} function.
21 | *
22 | * @return
23 | */
24 | abstract boolean isReal();
25 |
26 | /**
27 | * The number of elements in the array. Zero elements are counted. The real and imaginary components of a number are
28 | * together considered one element. This is equivalent to MATLAB's {@code numel} function.
29 | *
30 | * @return number of elements
31 | */
32 | abstract int getNumberOfElements();
33 |
34 | /**
35 | * Returns the length of the dimension specified by {@code dimension}. Dimensions use 0-based indexing. So the
36 | * first dimension, which is dimension 0, is the row length. The second dimension is the column length. The third
37 | * dimension and beyond are pages.
38 | *
39 | * @param dimension
40 | * @return length of {@code dimension}
41 | * @throws IllegalArgumentException if {@code dimension} is not a dimension of the array
42 | */
43 | abstract int getLengthOfDimension(int dimension);
44 |
45 | /**
46 | * Returns the number of dimensions of the array.
47 | *
48 | * @return number of dimensions
49 | */
50 | abstract int getNumberOfDimensions();
51 |
52 | /**
53 | * Returns an array that holds the real values from the MATLAB array. Each call returns a new copy which may be used
54 | * in any manner; modifications to it will have no effect on this instance.
55 | *
56 | * @return real array
57 | */
58 | abstract T toRealArray();
59 |
60 | /**
61 | * Returns an array that holds the imaginary values from the MATLAB array. Each call returns a new copy which may be
62 | * used in any manner; modifications to it will have no effect on this instance. If this array is real then the
63 | * returned array will be have the default value as all of its base elements.
64 | *
65 | * @return imaginary array
66 | */
67 | abstract T toImaginaryArray();
68 |
69 | /**
70 | * If this array has a sparse representation.
71 | *
72 | * @return
73 | */
74 | abstract boolean isSparse();
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/LocalHostRMIHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.io.IOException;
9 | import java.io.Serializable;
10 | import java.net.InetAddress;
11 | import java.net.ServerSocket;
12 | import java.net.Socket;
13 | import java.rmi.Remote;
14 | import java.rmi.RemoteException;
15 | import java.rmi.registry.LocateRegistry;
16 | import java.rmi.registry.Registry;
17 | import java.rmi.server.RMIClientSocketFactory;
18 | import java.rmi.server.RMIServerSocketFactory;
19 | import java.rmi.server.UnicastRemoteObject;
20 |
21 | import javax.net.ServerSocketFactory;
22 | import javax.net.SocketFactory;
23 |
24 | /**
25 | * Handles creation of RMI objects, making sure they only operate on localhost.
26 | *
27 | * @since 4.0.0
28 | *
29 | * @author Joshua Kaplan
30 | */
31 | class LocalHostRMIHelper {
32 | private static final LocalHostRMISocketFactory SOCKET_FACTORY = new LocalHostRMISocketFactory();
33 |
34 | public static Registry getRegistry(int port) throws RemoteException {
35 | return LocateRegistry.getRegistry("localhost", port, SOCKET_FACTORY);
36 | }
37 |
38 | public static Registry createRegistry(int port) throws RemoteException {
39 | return LocateRegistry.createRegistry(port, SOCKET_FACTORY, SOCKET_FACTORY);
40 | }
41 |
42 | public static Remote exportObject(Remote object) throws RemoteException {
43 | return UnicastRemoteObject.exportObject(object, 0, SOCKET_FACTORY, SOCKET_FACTORY);
44 | }
45 |
46 | private static class LocalHostRMISocketFactory implements RMIClientSocketFactory, RMIServerSocketFactory, Serializable {
47 | private static final long serialVersionUID = 2973279795727940224L;
48 |
49 | @Override
50 | public Socket createSocket(String host, int port) throws IOException {
51 | return SocketFactory.getDefault().createSocket(InetAddress.getByName("localhost"), port);
52 | }
53 |
54 | @Override
55 | public ServerSocket createServerSocket(int port) throws IOException {
56 | return ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"));
57 | }
58 |
59 | @Override
60 | public boolean equals(Object o) {
61 | return (o instanceof LocalHostRMISocketFactory);
62 | }
63 |
64 | @Override
65 | public int hashCode() {
66 | return 5;
67 | }
68 |
69 | /**
70 | * Overridden to provide a better name for the RMI RenewClean thread.
71 | *
72 | * @return
73 | */
74 | @Override
75 | public String toString() {
76 | return "MLC localhost Socket Factory";
77 | }
78 | }
79 |
80 | static class LocalHostRemoteObject extends UnicastRemoteObject {
81 | private static final long serialVersionUID = -7160502485279570444L;
82 |
83 | LocalHostRemoteObject() throws RemoteException {
84 | super(0, SOCKET_FACTORY, SOCKET_FACTORY);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | All code up to tags/original:
2 | Copyright (c) 2013, Joshua Kaplan
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6 | following conditions are met:
7 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
8 | disclaimer.
9 | - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
10 | following disclaimer in the documentation and/or other materials provided with the distribution.
11 | - Neither the name of matlabcontrol nor the names of its contributors may be used to endorse or promote products
12 | derived from this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
19 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
20 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 |
22 |
23 | All code after tags/original:
24 | Copyright (c) 2016, DiffPlug
25 | All rights reserved.
26 |
27 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
28 | following conditions are met:
29 | - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
30 | disclaimer.
31 | - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
32 | following disclaimer in the documentation and/or other materials provided with the distribution.
33 | - Neither the name of MatConsoleCtl nor the names of its contributors may be used to endorse or promote products
34 | derived from this software without specific prior written permission.
35 |
36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
37 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
40 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42 |
--------------------------------------------------------------------------------
/src/test/java/matlabcontrol/MatlabRequired.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol;
7 |
8 | import java.awt.BorderLayout;
9 | import java.awt.Container;
10 | import java.awt.event.WindowEvent;
11 | import java.util.concurrent.atomic.AtomicReference;
12 |
13 | import javax.swing.JButton;
14 | import javax.swing.JFrame;
15 | import javax.swing.JTextArea;
16 | import javax.swing.SwingUtilities;
17 |
18 | import org.junit.Assert;
19 |
20 | public class MatlabRequired {
21 | /** Marks that this test requires user-in-the-loop interaction with MATLAB. */
22 | public static class Interactive {
23 | /** Opens a dialog with the given instructions. Returns a runnable which closes the dialog. */
24 | public static Runnable prompt(final String instructions) {
25 | // figure out the name of the test from the stack
26 | StackTraceElement[] elements = new Throwable().getStackTrace();
27 | String testName = "unknown";
28 | for (int i = 1; i < elements.length; ++i) {
29 | if (!elements[i].getClassName().startsWith("matlabcontrol.")) {
30 | StackTraceElement element = elements[i - 1];
31 | testName = element.getClassName() + "::" + element.getMethodName();
32 | break;
33 | }
34 | }
35 | final String finalTestName = testName;
36 |
37 | // open a dialog and save it
38 | final AtomicReference box = new AtomicReference();
39 | SwingUtilities.invokeLater(new Runnable() {
40 | @Override
41 | public void run() {
42 | JFrame frame = new JFrame();
43 | box.set(frame);
44 | frame.setTitle(finalTestName);
45 |
46 | Container contentPane = frame.getContentPane();
47 | contentPane.setLayout(new BorderLayout());
48 |
49 | JTextArea label = new JTextArea();
50 | label.setText(instructions);
51 | contentPane.add(label, BorderLayout.CENTER);
52 |
53 | JButton button = new JButton();
54 | button.setText("Fail");
55 | contentPane.add(button, BorderLayout.SOUTH);
56 |
57 | frame.pack();
58 | frame.setVisible(true);
59 |
60 | button.addActionListener(new java.awt.event.ActionListener() {
61 | @Override
62 | public void actionPerformed(java.awt.event.ActionEvent evt) {
63 | Assert.fail("User clicked fail");
64 | }
65 | });
66 | }
67 | });
68 |
69 | // return a runnable which will close the dialog
70 | return new Runnable() {
71 | @Override
72 | public void run() {
73 | SwingUtilities.invokeLater(new Runnable() {
74 | @Override
75 | public void run() {
76 | JFrame frame = box.get();
77 | if (frame.isVisible()) {
78 | frame.setVisible(false);
79 | ;
80 | frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
81 | }
82 | }
83 | });
84 | }
85 | };
86 | }
87 | }
88 |
89 | /** Marks that this test requires MATLAB but no user. */
90 | public static class Headless {}
91 | }
92 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/ClassInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | import java.util.concurrent.ConcurrentHashMap;
9 | import java.util.concurrent.ConcurrentMap;
10 |
11 | /**
12 | *
13 | * @since 4.2.0
14 | * @author Joshua Kaplan
15 | */
16 | class ClassInfo {
17 | private static ConcurrentMap, ClassInfo> CACHE = new ConcurrentHashMap, ClassInfo>();
18 |
19 | static ClassInfo getInfo(Class> clazz) {
20 | ClassInfo info = CACHE.get(clazz);
21 | if (info == null) {
22 | info = new ClassInfo(clazz);
23 | CACHE.put(clazz, info);
24 | }
25 |
26 | return info;
27 | }
28 |
29 | /**
30 | * The class this information is about
31 | */
32 | final Class> describedClass;
33 |
34 | /**
35 | * If the class is either {@code void} or {@code java.lang.Void}
36 | */
37 | final boolean isVoid;
38 |
39 | /**
40 | * If the class is primitive
41 | */
42 | final boolean isPrimitive;
43 |
44 | /**
45 | * If an array type
46 | */
47 | final boolean isArray;
48 |
49 | /**
50 | * If the array's base component type is a primitive
51 | */
52 | final boolean isPrimitiveArray;
53 |
54 | /**
55 | * If the base component type of an array, {@code null} if not an array
56 | */
57 | final Class> baseComponentType;
58 |
59 | /**
60 | * The number of array dimensions, {@code 0} if not an array
61 | */
62 | final int arrayDimensions;
63 |
64 | /**
65 | * If the class is one of: {@code byte}, {@code Byte}, {@code short}, {@code Short}, {@code int},
66 | * {@code Integer}, {@code long}, {@code Long}, {@code float}, {@code Float}, {@code double}, {@code Double}
67 | */
68 | final boolean isBuiltinNumeric;
69 |
70 | /**
71 | * If the class inherits from {@code MatlabType}
72 | */
73 | final boolean isMatlabType;
74 |
75 | private ClassInfo(Class> clazz) {
76 | describedClass = clazz;
77 |
78 | isPrimitive = clazz.isPrimitive();
79 |
80 | if (clazz.isArray()) {
81 | isArray = true;
82 |
83 | int dim = 0;
84 | Class> type = clazz;
85 | while (type.isArray()) {
86 | dim++;
87 | type = type.getComponentType();
88 | }
89 |
90 | arrayDimensions = dim;
91 | baseComponentType = type;
92 | isPrimitiveArray = type.isPrimitive();
93 | } else {
94 | isArray = false;
95 | baseComponentType = null;
96 | isPrimitiveArray = false;
97 | arrayDimensions = 0;
98 | }
99 |
100 | isVoid = clazz.equals(Void.class) || clazz.equals(void.class);
101 | isMatlabType = MatlabType.class.isAssignableFrom(clazz);
102 |
103 | isBuiltinNumeric = clazz.equals(Byte.class) || clazz.equals(byte.class) ||
104 | clazz.equals(Short.class) || clazz.equals(short.class) ||
105 | clazz.equals(Integer.class) || clazz.equals(int.class) ||
106 | clazz.equals(Long.class) || clazz.equals(long.class) ||
107 | clazz.equals(Float.class) || clazz.equals(float.class) ||
108 | clazz.equals(Double.class) || clazz.equals(double.class);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at community@diffplug.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/link/MatlabDoubleFullMatrix.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.link;
7 |
8 | /**
9 |
10 | * @since 4.2.0
11 | * @author Joshua Kaplan
12 | */
13 | class MatlabDoubleFullMatrix extends MatlabDoubleMatrix {
14 | private final FullArray _array;
15 |
16 | MatlabDoubleFullMatrix(double[] real, double[] imag, int[] dimensions) {
17 | _array = new FullArray(double[].class, real, imag, dimensions);
18 | }
19 |
20 | MatlabDoubleFullMatrix(T real, T imag) {
21 | _array = new FullArray(double[].class, real, imag);
22 | }
23 |
24 | @Override
25 | BaseArray getBaseArray() {
26 | return _array;
27 | }
28 |
29 | @Override
30 | public double getRealElementAtLinearIndex(int linearIndex) {
31 | return _array._real[linearIndex];
32 | }
33 |
34 | @Override
35 | public double getImaginaryElementAtLinearIndex(int linearIndex) {
36 | return _array._imag == null ? 0 : _array._imag[linearIndex];
37 | }
38 |
39 | @Override
40 | public double getRealElementAtIndices(int row, int column) {
41 | return _array._real[_array.getLinearIndex(row, column)];
42 | }
43 |
44 | @Override
45 | public double getRealElementAtIndices(int row, int column, int page) {
46 | return _array._real[_array.getLinearIndex(row, column, page)];
47 | }
48 |
49 | @Override
50 | public double getRealElementAtIndices(int row, int column, int[] pages) {
51 | return _array._real[_array.getLinearIndex(row, column, pages)];
52 | }
53 |
54 | @Override
55 | public double getImaginaryElementAtIndices(int row, int column) {
56 | return _array._imag == null ? 0 : _array._imag[_array.getLinearIndex(row, column)];
57 | }
58 |
59 | @Override
60 | public double getImaginaryElementAtIndices(int row, int column, int page) {
61 | return _array._imag == null ? 0 : _array._imag[_array.getLinearIndex(row, column, page)];
62 | }
63 |
64 | @Override
65 | public double getImaginaryElementAtIndices(int row, int column, int[] pages) {
66 | return _array._imag == null ? 0 : _array._imag[_array.getLinearIndex(row, column, pages)];
67 | }
68 |
69 | @Override
70 | public MatlabDouble getElementAtLinearIndex(int linearIndex) {
71 | return new MatlabDouble(_array._real[linearIndex], _array._imag == null ? 0 : _array._imag[linearIndex]);
72 | }
73 |
74 | @Override
75 | public MatlabDouble getElementAtIndices(int row, int column) {
76 | int linearIndex = _array.getLinearIndex(row, column);
77 |
78 | return new MatlabDouble(_array._real[linearIndex], _array._imag == null ? 0 : _array._imag[linearIndex]);
79 | }
80 |
81 | @Override
82 | public MatlabDouble getElementAtIndices(int row, int column, int page) {
83 | int linearIndex = _array.getLinearIndex(row, column, page);
84 |
85 | return new MatlabDouble(_array._real[linearIndex], _array._imag == null ? 0 : _array._imag[linearIndex]);
86 | }
87 |
88 | @Override
89 | public MatlabDouble getElementAtIndices(int row, int column, int... pages) {
90 | int linearIndex = _array.getLinearIndex(row, column, pages);
91 |
92 | return new MatlabDouble(_array._real[linearIndex], _array._imag == null ? 0 : _array._imag[linearIndex]);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | # MatConsoleCtl releases
2 |
3 | ## [Unreleased]
4 |
5 | ## [4.6.1] - 2023-07-11
6 | - Support passing custom MATLAB environment & modify build gradle to OSGIfy(add the MANIFEST headers) the generated jar.
7 | - https://github.com/diffplug/matconsolectl/pull/27
8 |
9 | ## [4.6.0] - 2020-11-12
10 | - Added checks for directories and non-exisiting files in classpath converters: In Configuration.getClassPathAsRMICodebase() and Configuration.getClassPathAsCanonicalPaths(). This prevents unnecessary IOExceptions for invalid classpaths.
11 | - https://github.com/diffplug/matconsolectl/pull/21
12 |
13 | ## [4.5.0] - 2017-07-18
14 | - Added `Builder.setOutputWriter` and `Builder.setErrorWriter` for capturing `stdout` and `stderr` from MATLAB. ([#20](https://github.com/diffplug/matconsolectl/pull/20))
15 |
16 | ## [4.4.4] - 2016-12-15
17 | - Yet a better fix to a bug where MatConsoleCtl would not run if there were [spaces in the path](https://github.com/diffplug/matconsolectl/issues/15) to the MatConsoleCtl jar.
18 |
19 | ## [4.4.3] - 2016-12-15
20 | - Better fix to a bug where MatConsoleCtl would not run if there were [spaces in the path](https://github.com/diffplug/matconsolectl/issues/15) to the MatConsoleCtl jar.
21 |
22 | ## [4.4.2] - 2015-07-05
23 | - Fixed a bug where MatConsoleCtl would not run if there were [spaces in the path](https://github.com/diffplug/matconsolectl/issues/11) to the MatConsoleCtl jar.
24 |
25 | ## [4.4.1] - 2015-10-16
26 | - Corrected the license in the maven metadata.
27 |
28 | ## [4.4.0] - 2015-10-16
29 | - `MatlabType.MatlabTypeGetter` is now generic.
30 | - Fixed lots of compiler warnings.
31 | - Removed some [unused code](https://github.com/diffplug/matconsolectl/commit/c514188e55880528268dd3314f7347d95d00b7b6), and carefully marked code which [appears unused](https://github.com/diffplug/matconsolectl/commit/60564f2e8a80494b443d7da31c01d2e55c6d72c2) but is actually needed for internal MATLAB scripts.
32 | - Applied DiffPlug's standard formatting and code-quality plugins, FindBugs found several bugs.
33 | - [Fixed bug in ArrayUtils.equals when applied to arrays of long.](https://github.com/diffplug/matconsolectl/commit/088b954551392dc7b24142fd7f1cbcdc6a4005bf)
34 | - [Fixed a serialization bug.](https://github.com/diffplug/matconsolectl/commit/d6bc07adca74f0bb3ae91c1009222eff6b975774)
35 | - Broke up the test suite into `test`, `testMatlabHeadless`, and `testMatlabInteractive`
36 | - Moved the demo code into the main library. It's a very small demo with no dependencies, makes life easier to manage one jar rather than two.
37 |
38 | ## [4.3.0] - 1015-02-23
39 | - Added OSGi compatibility.
40 |
41 | ## [4.2.1] - 2015-02-22
42 | - ThrowableWrapper now initializes the `getMessage()` field with MATLAB's raw error text.
43 |
44 | ## [4.2.0] - 2015-02-20
45 | - Switched to gradle, which makes the jmistub subproject unnecessary.
46 | - Added `CopyPasteCallback` to the set of options for creating a `MatlabProxyFactory`. The factory sends a chunk of code to the callback, and the user copy-pastes this code into a MATLAB terminal to initiate a connection.
47 | + At first, I got a bunch of Serialization errors. There were a bunch of `Serializable` classes that didn't specify a `serialVersionUID`. Specifying these seemed to fix the problem.
48 | + You can connect over and over this way, and the MATLAB instance stays happy.
49 |
50 | ## Versions up to 4.1.0 are from the original matlabcontrol project on [Google code page](https://code.google.com/p/matlabcontrol/wiki/VersionHistory).
51 |
--------------------------------------------------------------------------------
/src/main/java/matlabcontrol/demo/ArrayPanel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Code licensed under new-style BSD (see LICENSE).
3 | * All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
4 | * All code after tags/original: Copyright (c) 2016, DiffPlug
5 | */
6 | package matlabcontrol.demo;
7 |
8 | import java.awt.Color;
9 | import java.awt.GridLayout;
10 | import java.util.ArrayList;
11 |
12 | import javax.swing.JComboBox;
13 | import javax.swing.JPanel;
14 | import javax.swing.JTextField;
15 |
16 | /**
17 | * The panel that contains the options to select elements of the array.
18 | *
19 | * @author Joshua Kaplan
20 | */
21 | @SuppressWarnings("serial")
22 | class ArrayPanel extends JPanel {
23 | //Input options: String or Double
24 | private static final int DOUBLE_INDEX = 0, STRING_INDEX = 1;
25 |
26 | private static final String[] OPTIONS = new String[2];
27 |
28 | static {
29 | OPTIONS[DOUBLE_INDEX] = "Double";
30 | OPTIONS[STRING_INDEX] = "String";
31 | }
32 |
33 | /**
34 | * Number of fields and drop down lists.
35 | */
36 | public static final int NUM_ENTRIES = 3;
37 |
38 | /**
39 | * Drop down lists to choose between object types.
40 | */
41 | private final JComboBox[] _optionBoxes;
42 |
43 | /**
44 | * Fields for inputting values.
45 | */
46 | private final JTextField[] _entryFields;
47 |
48 | public ArrayPanel() {
49 | super(new GridLayout(NUM_ENTRIES, 2));
50 | this.setBackground(Color.WHITE);
51 |
52 | //Drop down lists and input fields
53 | _optionBoxes = new JComboBox[NUM_ENTRIES];
54 | _entryFields = new JTextField[NUM_ENTRIES];
55 |
56 | for (int i = 0; i < NUM_ENTRIES; i++) {
57 | _optionBoxes[i] = new JComboBox(OPTIONS);
58 | _entryFields[i] = new JTextField(8);
59 | this.add(_optionBoxes[i]);
60 | this.add(_entryFields[i]);
61 | }
62 | }
63 |
64 | /**
65 | * Take the elements of the fields and put them into an array.
66 | *
67 | * @return
68 | */
69 | public Object[] getArray() {
70 | ArrayList