Wire#

Static JSON entry points. Each operation takes its inputs as JSON text, runs the matching engine call and returns a JSON envelope string: {"ok":true,"result":…} on success, {"ok":false,"error":…} when the engine reports an error. The per-project operations take a typed Project, so typed and JSON calls can work on the same instance. For a project used only through JSON, JsonProject wraps the same operations around a project it owns.

Wire has a private constructor and only static methods.

Declaration#

package org.dhtmlx.plen;

public final class Wire {
  public static String schedule(String data, String options)
  public static Project newProject(String options)

  public static String solve(Project project, String data, String options)
  public static String preview(Project project, String changes, String options)
  public static String analyze(Project project, String data, String options)
  public static String apply(Project project, String changes)
  public static String level(Project project, String options)
  public static String evaluate(Project project, String candidates, String options)
  public static String suggestAssignments(Project project, String slots, String options)
  public static String loadProfile(Project project, String options)
  public static String slots(Project project, String pool, String requirements)

  public static String envelopeText(Supplier<?> run)
  public static Object envelope(Supplier<?> run)
  public static String resultText(Object value)
  public static String errorText(PlenException e)
  public static Object error(PlenException e)
}

Supplier is java.util.function.Supplier. Every method is synchronous.

Envelopes and errors#

Every operation that returns String returns an envelope. Input fields use the snake_case names and the result fields follow the JSON contract described in JSON API.

{"ok":true,"result":{"baselineId":"1-c9a569b56aab2c77","conflicts":[],"converged":true,"cycles":[],"notes":[],"updates":[…]}}
{"error":{"code":null,"kind":"parse","message":"missing field `tasks`","path":null},"ok":false}
Error field Value
kind "parse" for an InputException of kind PARSE, "validation" for kind VALIDATION, "project" for a ProjectException.
message getMessage() of the exception. For a ProjectException, the kebab-case code.
path InputException.path, in wire spelling (tasks[3].constraint_date). null for parse errors and project errors.
code The kebab-case ProjectError ("no-baseline", "stale-baseline", "needs-resync"). null for input errors.

Only a PlenException becomes an error envelope. Decoding failures, including malformed JSON, duplicate keys, a missing required field and a JSON null document, are InputExceptions and come back as envelopes. Other exceptions propagate:

  • NullPointerException for a null project or a null JSON string. Only the data argument of solve and analyze accepts null
  • IllegalStateException when the result holds a NaN or infinite number, from Encode.text
  • OutOfMemoryError from slots with very large requirement counts

Results that carry their own problems, such as rejected operations in an ApplyReport or conflicts in a ScheduleResult, are success envelopes.

Static methods#

schedule#

public static String schedule(String data, String options)

Decodes the project data and options, runs Engine.schedule and returns the envelope. Stateless: nothing is kept between calls.

Name Type Description
data String ProjectData JSON.
options String SolveOptions JSON. Pass "{}" for the defaults.

Returns an envelope with a ScheduleResult.

newProject#

public static Project newProject(String options)

Decodes the options and creates an empty, unsolved Project.

Name Type Description
options String ProjectOptions JSON, such as {"validation":"repair"}. Pass "{}" for strict validation.

Returns the new Project, not an envelope.

Errors throws InputException when the options JSON doesn't decode.

solve#

public static String solve(Project project, String data, String options)

Runs Project#solve on project.

Name Type Description
project Project The project to solve.
data String ProjectData JSON. Nullable; null re-solves the current state.
options String SolveOptions JSON.

Returns an envelope with a ScheduleResult.

preview#

public static String preview(Project project, String changes, String options)

Runs Project#preview on project.

Name Type Description
project Project A solved project.
changes String SchedulingChanges JSON.
options String PreviewOptions JSON.

Returns an envelope with a ScheduleResult.

analyze#

public static String analyze(Project project, String data, String options)

Runs Project#analyze on project.

Name Type Description
project Project The project to analyze.
data String ProjectData JSON with the dates to analyze. Nullable; null uses the project's current dates.
options String AnalyzeOptions JSON.

Returns an envelope with a ScheduleResult.

apply#

public static String apply(Project project, String changes)

Runs Project#apply on project.

Name Type Description
project Project The project to edit.
changes String SchedulingChanges JSON.

Returns an envelope with an ApplyReport.

level#

public static String level(Project project, String options)

Runs Project#level on project.

Name Type Description
project Project The project to level.
options String LevelingOptions JSON.

Returns an envelope with a LevelingResult.

evaluate#

public static String evaluate(Project project, String candidates, String options)

Runs Project#evaluate on project.

Name Type Description
project Project A solved project.
candidates String JSON array of Candidate objects. A null element is a parse error.
options String EvaluateOptions JSON.

Returns an envelope with an EvaluateResult.

suggestAssignments#

public static String suggestAssignments(Project project, String slots, String options)

Runs Project#suggestAssignments on project.

Name Type Description
project Project A solved project.
slots String JSON array of Slot objects. A null element is a parse error.
options String SuggestOptions JSON.

Returns an envelope with a SuggestResult.

loadProfile#

public static String loadProfile(Project project, String options)

Runs Project#loadProfile on project.

Name Type Description
project Project A solved project.
options String LoadProfileOptions JSON.

Returns an envelope with a LoadProfile.

slots#

public static String slots(Project project, String pool, String requirements)

Runs SkillLayer.slots on project. A MatchException is converted with toPlenException(), so invalid pools and requirements come back as error envelopes.

Name Type Description
project Project A solved project.
pool String Pool JSON.
requirements String JSON array of Requirement objects. A null element is a parse error.

Returns an envelope with the array of Slot objects.

envelopeText#

public static String envelopeText(Supplier<?> run)

Calls run, encodes its return value with Encode.text and wraps it in a success envelope. A PlenException thrown by run becomes an error envelope, as from errorText. Every other exception propagates.

Name Type Description
run Supplier<?> The call to run. It must return a result type that Encode.text accepts, such as ScheduleResult or ApplyReport.

Returns the envelope as JSON text.

Errors UnsupportedOperationException when Encode.text has no encoder for the returned value; IllegalStateException when the value holds a NaN or infinite number.

envelope#

public static Object envelope(Supplier<?> run)

Same as envelopeText, parsed with Json.parse.

Returns the envelope as a JSON tree: Map<String, Object>, List<Object>, String, Boolean, null, and numbers as Long or Double. Read numbers as Number.

resultText#

public static String resultText(Object value)

Wraps an already computed typed result in a success envelope.

Name Type Description
value Object A result type that Encode.text accepts.

Returns {"ok":true,"result":…} as JSON text.

Errors same as envelopeText for the encoding step.

errorText#

public static String errorText(PlenException e)

Builds the error envelope for an engine exception. Keys are sorted: {"error":{"code":…,"kind":…,"message":…,"path":…},"ok":false}. The field values are listed in Envelopes and errors.

Name Type Description
e PlenException An InputException or a ProjectException.

Returns the error envelope as JSON text.

error#

public static Object error(PlenException e)

Same as errorText, parsed with Json.parse.

Returns the error envelope as a JSON tree.

Example#

Load and solve a project from JSON, edit it through the typed API, then read the result back as JSON:

import org.dhtmlx.plen.*;

public class WireExample {
  public static void main(String[] args) throws Exception {
    Project project = Wire.newProject("{}");

    String data = "{\"tasks\":["
        + "{\"id\":\"a\",\"start_date\":\"2026-03-02\",\"duration\":2},"
        + "{\"id\":\"b\",\"start_date\":\"2026-03-02\",\"duration\":1}],"
        + "\"links\":[{\"id\":\"ab\",\"source\":\"a\",\"target\":\"b\"}]}";
    System.out.println(Wire.solve(project, data, "{\"includeUnchanged\":true}"));

    // typed edit on the same project
    project.apply(Decode.fromJson(
        "{\"tasks\":{\"update\":[{\"id\":\"a\",\"duration\":3}]}}",
        SchedulingChanges.class));

    // typed call, JSON envelope out
    System.out.println(Wire.envelopeText(() -> project.solve(null, new SolveOptions())));

    // engine errors come back as envelopes
    System.out.println(Wire.preview(project, "{\"baselineId\":\"old\"}", "{}"));
  }
}

The last call prints:

{"error":{"code":"stale-baseline","kind":"project","message":"stale-baseline","path":null},"ok":false}
  • JsonProject - the same operations on a project used only through JSON
  • Project - the typed project the operations run on
  • Encode - writes the result of a success envelope
  • Decode - decodes the input JSON into typed records
  • Exchange JSON with a client - reading envelopes and mixing typed and JSON calls