Skip to content

Commit 67303fa

Browse files
authored
[REST] New REST APIs to generate DSL syntax for items and things (#4569)
* [REST] New REST APIs to generate DSL syntax for items and things Related to #4509 Signed-off-by: Laurent Garnier <[email protected]>
1 parent e16b52d commit 67303fa

File tree

16 files changed

+1444
-23
lines changed

16 files changed

+1444
-23
lines changed

bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/fileformat/FileFormatResource.java

+421
Large diffs are not rendered by default.

bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/ModelRepository.java

+12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package org.openhab.core.model.core;
1414

1515
import java.io.InputStream;
16+
import java.io.OutputStream;
1617
import java.util.Set;
1718

1819
import org.eclipse.emf.ecore.EObject;
@@ -26,6 +27,7 @@
2627
* come from.
2728
*
2829
* @author Kai Kreuzer - Initial contribution
30+
* @author Laurent Garnier - Added method generateSyntaxFromModel
2931
*/
3032
@NonNullByDefault
3133
public interface ModelRepository {
@@ -92,4 +94,14 @@ public interface ModelRepository {
9294
* @param listener the listener to remove
9395
*/
9496
void removeModelRepositoryChangeListener(ModelRepositoryChangeListener listener);
97+
98+
/**
99+
* Generate the syntax from a provided model content.
100+
*
101+
* @param out the output stream to write the generated syntax to
102+
* @param modelType the model type
103+
* @param modelContent the content of the model
104+
* @return the corresponding syntax
105+
*/
106+
void generateSyntaxFromModel(OutputStream out, String modelType, EObject modelContent);
95107
}

bundles/org.openhab.core.model.core/src/main/java/org/openhab/core/model/core/internal/ModelRepositoryImpl.java

+23-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.io.ByteArrayInputStream;
1616
import java.io.IOException;
1717
import java.io.InputStream;
18+
import java.io.OutputStream;
1819
import java.nio.charset.StandardCharsets;
1920
import java.text.MessageFormat;
2021
import java.util.ArrayList;
@@ -50,6 +51,7 @@
5051
* @author Kai Kreuzer - Initial contribution
5152
* @author Oliver Libutzki - Added reloadAllModelsOfType method
5253
* @author Simon Kaufmann - added validation of models before loading them
54+
* @author Laurent Garnier - Added method generateSyntaxFromModel
5355
*/
5456
@Component(immediate = true)
5557
@NonNullByDefault
@@ -64,6 +66,8 @@ public class ModelRepositoryImpl implements ModelRepository {
6466

6567
private final SafeEMF safeEmf;
6668

69+
private int counter;
70+
6771
@Activate
6872
public ModelRepositoryImpl(final @Reference SafeEMF safeEmf) {
6973
this.safeEmf = safeEmf;
@@ -171,7 +175,8 @@ public Iterable<String> getAllModelNamesOfType(final String modelType) {
171175

172176
return resourceListCopy.stream()
173177
.filter(input -> input.getURI().lastSegment().contains(".") && input.isLoaded()
174-
&& modelType.equalsIgnoreCase(input.getURI().fileExtension()))
178+
&& modelType.equalsIgnoreCase(input.getURI().fileExtension())
179+
&& !input.getURI().lastSegment().startsWith("tmp_"))
175180
.map(from -> from.getURI().path()).toList();
176181
}
177182
}
@@ -227,6 +232,23 @@ public void removeModelRepositoryChangeListener(ModelRepositoryChangeListener li
227232
listeners.remove(listener);
228233
}
229234

235+
@Override
236+
public void generateSyntaxFromModel(OutputStream out, String modelType, EObject modelContent) {
237+
String result = "";
238+
synchronized (resourceSet) {
239+
String name = "tmp_generated_syntax_%d.%s".formatted(++counter, modelType);
240+
Resource resource = resourceSet.createResource(URI.createURI(name));
241+
try {
242+
resource.getContents().add(modelContent);
243+
resource.save(out, Map.of(XtextResource.OPTION_ENCODING, StandardCharsets.UTF_8.name()));
244+
} catch (IOException e) {
245+
logger.warn("Exception when saving the model {}", resource.getURI().lastSegment());
246+
} finally {
247+
resourceSet.getResources().remove(resource);
248+
}
249+
}
250+
}
251+
230252
private @Nullable Resource getResource(String name) {
231253
return resourceSet.getResource(URI.createURI(name), false);
232254
}

bundles/org.openhab.core.model.item/bnd.bnd

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Import-Package: javax.measure,\
2121
org.openhab.core.i18n,\
2222
org.openhab.core.items,\
2323
org.openhab.core.items.dto,\
24+
org.openhab.core.items.fileconverter,\
2425
org.openhab.core.library.items,\
2526
org.openhab.core.library.types,\
2627
org.openhab.core.thing.util,\

bundles/org.openhab.core.model.item/src/org/openhab/core/model/ItemsRuntimeModule.xtend

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,24 @@ org.openhab.core.model
1818

1919
import com.google.inject.Binder
2020
import com.google.inject.name.Names
21+
import org.openhab.core.model.formatting.ItemsFormatter
2122
import org.openhab.core.model.internal.valueconverter.ItemValueConverters
2223
import org.eclipse.xtext.conversion.IValueConverterService
24+
import org.eclipse.xtext.formatting.IFormatter
2325
import org.eclipse.xtext.linking.lazy.LazyURIEncoder
2426

2527
/**
2628
* Use this class to register components to be used at runtime / without the Equinox extension registry.
2729
*/
2830
class ItemsRuntimeModule extends AbstractItemsRuntimeModule {
29-
3031
override Class<? extends IValueConverterService> bindIValueConverterService() {
3132
return ItemValueConverters
3233
}
33-
34+
35+
override Class<? extends IFormatter> bindIFormatter() {
36+
return ItemsFormatter
37+
}
38+
3439
override void configureUseIndexFragmentsForLazyLinking(Binder binder) {
3540
binder.bind(Boolean.TYPE).annotatedWith(Names.named(LazyURIEncoder.USE_INDEXED_FRAGMENTS_BINDING)).toInstance(
3641
Boolean.FALSE)

bundles/org.openhab.core.model.item/src/org/openhab/core/model/formatting/ItemsFormatter.xtend

+18-6
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ class ItemsFormatter extends AbstractDeclarativeFormatter {
2626

2727
override protected void configureFormatting(FormattingConfig c) {
2828
c.setLinewrap(1, 1, 2).before(modelGroupItemRule)
29-
c.setLinewrap(1, 1, 2).before(modelItemTypeRule)
29+
c.setLinewrap(1, 1, 2).before(modelNormalItemRule)
3030

3131
c.setNoSpace().withinKeywordPairs("<", ">")
3232
c.setNoSpace().withinKeywordPairs("(", ")")
33+
c.setNoSpace().withinKeywordPairs("[", "]")
3334

34-
c.setIndentationIncrement.after(modelItemTypeRule)
35-
c.setIndentationDecrement.before(modelItemTypeRule)
36-
c.setIndentationIncrement.after(modelGroupItemRule)
37-
c.setIndentationDecrement.before(modelGroupItemRule)
35+
c.setNoSpace().around(":", "=")
36+
c.setNoSpace().before(",")
37+
38+
c.autoLinewrap = 400
3839

39-
c.autoLinewrap = 160
4040
c.setLinewrap(0, 1, 2).before(SL_COMMENTRule)
4141
c.setLinewrap(0, 1, 2).before(ML_COMMENTRule)
4242
c.setLinewrap(0, 1, 1).after(ML_COMMENTRule)
@@ -48,4 +48,16 @@ class ItemsFormatter extends AbstractDeclarativeFormatter {
4848
locator.before(pair.second)
4949
}
5050
}
51+
52+
def around(FormattingConfig.ElementLocator locator, String ... listKW) {
53+
for (keyword : findKeywords(listKW)) {
54+
locator.around(keyword)
55+
}
56+
}
57+
58+
def before(FormattingConfig.ElementLocator locator, String ... listKW) {
59+
for (keyword : findKeywords(listKW)) {
60+
locator.before(keyword)
61+
}
62+
}
5163
}

0 commit comments

Comments
 (0)