镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Reimplement MirthPlainDocument without Sun-derived code - #484

Open
tonygermano wants to merge 2 commits into
OpenIntegrationEngine:mainfrom
tonygermano:fix/mirth-plain-document
Open

tonygermano wants to merge 2 commits into
OpenIntegrationEngine:mainfrom
tonygermano:fix/mirth-plain-document

Conversation

@tonygermano

Copy link
Copy Markdown
Member

Fixes #473

org.syntax.jedit.MirthPlainDocument was a 2007 copy of the Java 1.5 javax.swing.text.PlainDocument source, and it still carried Sun's "PROPRIETARY/CONFIDENTIAL" header, which is not compatible with the project's MPL-2.0 license. This PR replaces it with an original implementation that extends PlainDocument instead of copying it.

What the old copy changed

Compared with the JDK 17 and 25 PlainDocument (which are identical apart from one javadoc tag), the copy only changed two things:

  • Lines break on a lone CR as well as on LF, with CRLF counted as one break, so CR-delimited HL7 shows one segment per line in the jEdit text area.
  • The default tab size is 4 instead of 8.

Everything else was the JDK's code, plus private copies of two package-private helpers it needed because it lived outside javax.swing.text.

How the new class works

  • MirthPlainDocument now extends PlainDocument and sets the tab size to 4.
  • PlainDocument finds line breaks with a single read of the inserted text, splitting after each LF. The document's content is a small GapContent subclass that reports each lone CR as an LF for that one read only, using a copy of the text. PlainDocument therefore puts the breaks in the same places, the stored text is unchanged, and each insert still produces a single root element change, which JEditTextArea and SyntaxDocument rely on.
  • The translation is tied to the inserting thread and is cleared after the first read, so getText, painting, tokenizing, and the bidi and multibyte checks in AbstractDocument always see the real characters.
  • The class moved from the third-party org.syntax.jedit package to com.mirth.connect.client.ui.components, next to MirthSyntaxTextArea.
  • The unused MirthPlainDocument(Content) constructor was removed.

Commits

  1. Add tests for MirthPlainDocument line breaks. These are characterization tests, committed first and passing against the old Sun-derived class. They cover:
    • CR, LF, CRLF and LFCR line breaks
    • joining and splitting CRLF through edits
    • one root element change per insert
    • removing text across lines
    • undo and redo
    • the stored text being unchanged
    • the tab size
    • right-to-left Hebrew and Arabic lines and their bidi levels, and mixed-direction lines
    • bidi control characters
    • CJK and supplementary characters
    • input-method composed text
  2. Reimplement MirthPlainDocument on top of PlainDocument. Replaces the class. The same tests pass unchanged.

Known behavior (unchanged)

The old class did both of these too:

  • Inserting a lone CR immediately before an existing LF (for example, pasting text that ends in a bare CR at the end of an LF-terminated line) shows the LF on its own line until the text is reloaded.
  • Deleting a character between a CR and an LF leaves them on two lines until the text is reloaded.

In both cases the stored text is correct, so only the display is affected.

Testing

  • ./gradlew :client:test passes.
  • A side-by-side fuzz comparison of the old and new classes ran 100,000 random insert and remove sequences, including composed, bidi and multibyte text. Line maps, element changes and text were identical in every case.
  • Manual testing in the client:
    • the transformer's inbound message template
    • the Channel Writer template
    • the Send Message dialog

Tip: If testing manually, right click in the text area and select "Show Line Endings."

🤖 Generated with Claude Code

MirthPlainDocument differs from PlainDocument mainly in treating a lone
CR as a line break, so CR-delimited HL7 shows one segment per line,
while CRLF stays a single break. Pin down that behavior before the class
is rewritten: line boundaries for CR, LF, CRLF and LFCR, joining and
splitting CRLF through edits, one root element change per insert,
removal across lines, undo/redo, the unchanged text, and the tab size
of 4.

Also cover text in other scripts: right-to-left Hebrew and Arabic lines
with their bidi levels, mixed-direction lines, bidi control characters,
CJK and supplementary characters, and input method composed text.

Issue: OpenIntegrationEngine#473
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Tony Germano <tony@germano.name>
MirthPlainDocument was a copy of the Java 1.5 PlainDocument source with
its Sun proprietary header, which is not compatible with the project's
license. The only behavior it changed was to break lines on a lone CR
as well as LF, plus a default tab size of 4 instead of 8.

Extend PlainDocument instead and keep only those two changes.
PlainDocument builds its line map from a single read of the inserted
text, splitting after each LF. The document's content now reports lone CRs
as LFs for that one read, on a copy of the text, so PlainDocument puts
the breaks in the same places while the stored text stays unchanged and
each insert still produces a single root element change. The
translation is tied to the inserting thread, since getText does not take
the document lock and another thread could otherwise make that read.

Drop the constructor that takes a Content, since nothing uses it and
the line breaks depend on the document's own content.

Move the class out of the third-party org.syntax.jedit package into
com.mirth.connect.client.ui.components, next to MirthSyntaxTextArea,
which uses it through SyntaxDocument.

Issue: OpenIntegrationEngine#473
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Tony Germano <tony@germano.name>
@tonygermano
tonygermano requested a review from a team October 11, 2026 08:27
@tonygermano tonygermano added the licensing Eclipse Intellectual Property (IP) due diligence: licensing, provenance, Dash results, IP reviews label Oct 11, 2026
@github-actions

Copy link
Copy Markdown

Test Results

129 files  + 1  129 suites  +1   4m 0s ⏱️ + 1m 35s
748 tests +19  748 ✅ +19  0 💤 ±0  0 ❌ ±0 
838 runs  +19  832 ✅ +19  6 💤 ±0  0 ❌ ±0 

Results for commit 1264fd0. ± Comparison against base commit a13e6af.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

licensing Eclipse Intellectual Property (IP) due diligence: licensing, provenance, Dash results, IP reviews

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rewrite MirthPlainDocument

1 participant