Skip to main content



      Home
Home » Eclipse Projects » Eclipse Scout » [Neon][SDK] access Scout Model
[Neon][SDK] access Scout Model [message #1720512] Tue, 19 January 2016 01:45 Go to next message
Eclipse UserFriend
As the SDK is also available as standard Maven dependencies, I tried to access the Scout Model of a form class. I've downloaded the SDKs sources and tried to find a hint how to access it, but I didn't find a solution.

So far I found and tested:

File f = new File("xxxx/src/main/java");
Classpath cp = WorkspaceFileSystem.createClasspath(f, true, null);
ClasspathEntry classpathEntry = new ClasspathEntry(cp, StandardCharsets.UTF_8.name());
Collection<ClasspathEntry> all = new ArrayList<>();
all.add(classpathEntry);
JavaEnvironmentSpi javaEnvironment = new JavaEnvironmentWithJdt(all.toArray(new ClasspathEntry[all.size()]));
IJavaEnvironment wrap = javaEnvironment.wrap();
IType type = wrap.findType("xxxx.MyForm");
for (IMethod m : type.methods().list()) {
	System.out.println(m.source().toString());
}

But how can I get access to the Scout Model of this class. i.e. I would like to add a form field, or generate a form class from scratch.
Re: [Neon][SDK] access Scout Model [message #1720563 is a reply to message #1720512] Tue, 19 January 2016 05:30 Go to previous messageGo to next message
Eclipse UserFriend
The scout sdk is split up into a part that is independent of osgi/eclipse-osgi-jdt and another part that does the glueing with the osgi/eclipse-osgi-jdt.

The independent part is in the modules
org.eclipse.scout.sdk.core
org.eclipse.scout.sdk.core.s

(The latter is scouts usage of org.eclipse.scout.sdk.core for FormData, PageData etc.)

The eclipse-osgi-jdt glueing part is in the modules

org.eclipse.scout.sdk.s2e
org.eclipse.scout.sdk.s2e.ui


When doing non-osgi/non-workbench code you may take a look at the test modules of scout sdk.
In particular the class org.eclipse.scout.sdk.core.testing.JavaEnvironmentBuilder and org.eclipse.scout.sdk.core.model.TypeTest.

When doing osgi/workbench code take a look at org.eclipse.scout.sdk.s2e.ScoutSdkCore and org.eclipse.scout.sdk.s2e.util.S2eUtils
In particular org.eclipse.scout.sdk.s2e.ScoutSdkCore#createJavaEnvironment(IJavaProject jdtJavaProject)

IJavaEnvironment scoutJavaEnv=ScoutSdkCore.createJavaEnvironment(jdtJavaProject)


A jdtJavaProject can be obtained by a jdtType (IType.getJavaProject)
or
IProject jdtProject = ResourcesPlugin.getWorkspace().getRoot().getProject("my.project.name");
IJavaProject jdtJavaProject = JavaCore.create(jdtProject);


Now to your example:
Scout SDK tries (but does not require) to resolve all references that are used by the folders that is wrapped into a IJavaEnvironment.
This means when creaeting valid java code you may also add the pathts to the jre of the target project and not just the src/main/java folder.

Your code might copy/paste the source of JavaEnvironmentBuilder from the test suite and use what is useful for your purposes:

Then the code simply looks like:

String projectPath = "xxxx";

IJavaEnvironment env = new JavaEnvironmentBuilder()
.withAbsoluteSourcePath(projectPath + "/src/main/java")
.withRunningClasspath(true)//add jre paths and your running sdk code
.without("your.sdk.code.package.name")//remove your sdk code
.build();

IType type = env.findType("yyyy.MyForm");//fully qualified type name
for (IMethod m : type.methods().list()) {
System.out.println(m.source().toString());
//you may also use this, it writes to system.out when run outside of osgi. It writes to the IDE console when run inside the IDE.
SdkLog.info("Method {} has {} arguments",m.elementName(),m.parameters().list().size());
}

Re: [Neon][SDK] access Scout Model [message #1720604 is a reply to message #1720563] Tue, 19 January 2016 12:00 Go to previous messageGo to next message
Eclipse UserFriend
Thank you Ivan for your explications.

I would like to know whether there is a possibility to have in SDK an ScoutForm Object (i.e. ScoutForm form = ScoutSDK.getForm(IType type) and then for example a method addFormField(...) which would add the form fields inner class to the form, the getter for the FormField and even give the possibility to regenerate the FormData?
Re: [Neon][SDK] access Scout Model [message #1720844 is a reply to message #1720604] Thu, 21 January 2016 06:21 Go to previous messageGo to next message
Eclipse UserFriend
Hi René

What exactly do you want to do?
Are you writing code that should modify Scout Java files outside of the Eclipse IDE?
Or do you want to create inner classes in an existing java file which is open in the JavaEditor within Eclipse? Or something else?

Thanks for clarifying

[Updated on: Fri, 22 January 2016 11:48] by Moderator

Re: [Neon][SDK] access Scout Model [message #1723047 is a reply to message #1720844] Thu, 11 February 2016 04:10 Go to previous messageGo to next message
Eclipse UserFriend
Hi Matthias

sorry for long delay.

It could be both, but to be independent of Eclipse I would prefer modifying and creating Scout Java Files outside the Eclipse SDK (i.e. Maven Plugin).

The use cases I could imagine:
- during migration to Neon: automatize some code enhancements
- prototyping: use any sources describing the layout of an application (xml files, dsl, ...) and generate Scout Java Code (Forms,...). In the meantime I've learned that there was some work done in this direction: https://github.com/BSI-Business-Systems-Integration-AG/org.eclipse.scout.xtext/tree/master/org.eclipse.scout.saml


long story short: is there an API with functions like:
ScoutSDKForm form = createScoutForm(...)
ScoutSDKField field = form.addField(...) -> generates innerclass and accessors...
ScoutSDKForm form = readScoutForm(File javaSource)

Thanks
Re: [Neon][SDK] access Scout Model [message #1724278 is a reply to message #1723047] Mon, 22 February 2016 12:38 Go to previous messageGo to next message
Eclipse UserFriend
Hi René

If you want to stay IDE independent you can only use the API provided by org.eclipse.scout.sdk.core and org.eclipse.scout.sdk.core.s (both available on Maven Central).

Basically this API consists of two components:

  1. A parser that is capable to read java or class files into a structural memory representation including validation.
  2. Source Builders that are capable to create new java source


With this API you can apply a lot of modifications to java files (new or existing ones) but it is more low level than the example you provided.

You can use the following sample test case as starting point. It adds a new string field to an existing form including the form field getter method:

import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.scout.sdk.core.model.api.Flags;
import org.eclipse.scout.sdk.core.model.api.IJavaEnvironment;
import org.eclipse.scout.sdk.core.model.api.IType;
import org.eclipse.scout.sdk.core.model.spi.internal.ClasspathEntry;
import org.eclipse.scout.sdk.core.model.spi.internal.JavaEnvironmentWithJdt;
import org.eclipse.scout.sdk.core.s.IScoutRuntimeTypes;
import org.eclipse.scout.sdk.core.s.model.ScoutMethodSourceBuilderFactory;
import org.eclipse.scout.sdk.core.signature.Signature;
import org.eclipse.scout.sdk.core.sourcebuilder.compilationunit.CompilationUnitSourceBuilder;
import org.eclipse.scout.sdk.core.sourcebuilder.type.ITypeSourceBuilder;
import org.eclipse.scout.sdk.core.sourcebuilder.type.TypeSourceBuilder;
import org.eclipse.scout.sdk.core.testing.CoreTestingUtils;
import org.eclipse.scout.sdk.core.util.CoreUtils;
import org.junit.Test;

public class StringFieldAddTest {
  @Test
  public void testAddStringField() {

    IJavaEnvironment env = new JavaEnvironmentWithJdt(null, createClasspath()).wrap();

    // get existing form
    IType form = env.findType("formdata.client.ui.forms.ListBoxForm");

    // convert from parsed class to source builder (for modifications)
    CompilationUnitSourceBuilder cuBuilder = new CompilationUnitSourceBuilder(form.compilationUnit());

    // get existing mainbox builder
    ITypeSourceBuilder mainBoxBuilder = getTypeSourceBuilder(cuBuilder.getMainType(), "MainBox");

    // add string field
    ITypeSourceBuilder newStringField = new TypeSourceBuilder("MyNewStringField");
    newStringField.setFlags(Flags.AccPublic);
    newStringField.setSuperTypeSignature(Signature.createTypeSignature(IScoutRuntimeTypes.AbstractStringField));
    mainBoxBuilder.addType(newStringField);

    // add getter
    cuBuilder.getMainType().addMethod(ScoutMethodSourceBuilderFactory.createFieldGetter(Signature.createTypeSignature(newStringField.getFullyQualifiedName())));

    // create new source
    String source = CoreUtils.createJavaCode(cuBuilder, env, "\n", null);
    System.out.println(source);

    // validate result
    CoreTestingUtils.assertNoCompileErrors(env, cuBuilder.getPackageName(), cuBuilder.getMainType().getElementName(), source);
  }

  private static ClasspathEntry[] createClasspath() {
    String encoding = StandardCharsets.UTF_8.name(); // TODO specify the encoding of the files
    File[] classpathEntries = new File[]{}; //TODO fill classpath entries
    ClasspathEntry[] entries = new ClasspathEntry[classpathEntries.length];
    for (int i = 0; i < entries.length; i++) {
      boolean isSource = true; // TODO: specifies if classpathEntries[i] references a source jar/folder containing .java files OR a binary jar/folder containing .class files.
      Classpath cp = FileSystem.getClasspath(classpathEntries[i].getAbsolutePath(), encoding, isSource, null, null);
      entries[i] = new ClasspathEntry(cp, encoding);
    }
    return entries;
  }

  private static ITypeSourceBuilder getTypeSourceBuilder(ITypeSourceBuilder declaringType, String name) {
    for (ITypeSourceBuilder tsb : declaringType.getTypes()) {
      if (name.equals(tsb.getElementName())) {
        return tsb;
      }
    }
    return null;
  }
}


There are some TODOs in the code where you have to build the classpath of the environment you are working in.

As you can see the API is quite low level but at the same time very flexible.
Therefore for some components there are dedicated builders: There is e.g. a FormSourceBuilder that can create new forms, specific builders for DTOs like a FormData or builders for services, codetypes, pages, etc. Those components can then be stitched together to build complex components.

Hope this helps
Matthias
Re: [Neon][SDK] access Scout Model [message #1724323 is a reply to message #1724278] Tue, 23 February 2016 02:39 Go to previous message
Eclipse UserFriend
Thank you Matthias
this is exactly what I was looking for.
I will try to do some samples.
Previous Topic:[Neon] Validation on a date field
Next Topic:[Mars][HowTo] insert multi records in SQL.insert statement
Goto Forum:
  


Current Time: Tue Oct 28 05:51:22 EDT 2025

Powered by FUDForum. Page generated in 0.06048 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top