Skip to content

Commit 00b6a47

Browse files
authored
[REST] New API for conversion between file format and JSON (#4793)
* [REST] New API for conversion between file format and JSON Related to #4585 This PR supports conversion of things and items. It supports DSL and YAML file formats. A first new API (POST /file-format/create) allows to create a file format (DSL or YAML) from a JSON object. A second new API (POST /file-format/parse) allows to parse a file format (DSL or YAML) to a JSON object. These 2 APIs should help Main UI displaying DSL and YAML file formats for things. Signed-off-by: Laurent Garnier <lg.hc@free.fr>
1 parent 0f70493 commit 00b6a47

29 files changed

Lines changed: 1861 additions & 332 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2010-2025 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.io.rest.core.fileformat;
14+
15+
import java.util.List;
16+
17+
/**
18+
* This is a data transfer object to serialize the different components that can be contained
19+
* in a file format (items, things, ...) including an optional list of warnings.
20+
*
21+
* @author Laurent Garnier - Initial contribution
22+
*/
23+
public class ExtendedFileFormatDTO extends FileFormatDTO {
24+
25+
public List<String> warnings;
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2010-2025 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.io.rest.core.fileformat;
14+
15+
import java.util.Map;
16+
17+
/**
18+
* This is a data transfer object to serialize a channel link for an item contained in a file format.
19+
*
20+
* @author Laurent Garnier - Initial contribution
21+
*/
22+
public class FileFormatChannelLinkDTO {
23+
24+
public String channelUID;
25+
public Map<String, Object> configuration;
26+
27+
public FileFormatChannelLinkDTO(String channelUID, Map<String, Object> configuration) {
28+
this.channelUID = channelUID;
29+
this.configuration = configuration;
30+
}
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2010-2025 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.io.rest.core.fileformat;
14+
15+
import java.util.List;
16+
17+
import org.openhab.core.thing.dto.ThingDTO;
18+
19+
/**
20+
* This is a data transfer object to serialize the different components that can be contained
21+
* in a file format (items, things, ...).
22+
*
23+
* @author Laurent Garnier - Initial contribution
24+
*/
25+
public class FileFormatDTO {
26+
27+
public List<FileFormatItemDTO> items;
28+
public List<ThingDTO> things;
29+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2010-2025 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.io.rest.core.fileformat;
14+
15+
import java.util.List;
16+
import java.util.Map;
17+
18+
import org.openhab.core.items.dto.GroupFunctionDTO;
19+
import org.openhab.core.items.dto.GroupItemDTO;
20+
import org.openhab.core.items.dto.ItemDTO;
21+
import org.openhab.core.items.dto.MetadataDTO;
22+
23+
/**
24+
* This is a data transfer object to serialize an item contained in a file format.
25+
*
26+
* @author Laurent Garnier - Initial contribution
27+
*/
28+
public class FileFormatItemDTO extends ItemDTO {
29+
30+
public String groupType;
31+
public GroupFunctionDTO function;
32+
public String format;
33+
public Map<String, MetadataDTO> metadata;
34+
public List<FileFormatChannelLinkDTO> channelLinks;
35+
36+
public FileFormatItemDTO(ItemDTO itemDTO, boolean isGroup) {
37+
this.type = itemDTO.type;
38+
this.name = itemDTO.name;
39+
this.label = itemDTO.label;
40+
this.category = itemDTO.category;
41+
this.tags = itemDTO.tags;
42+
this.groupNames = itemDTO.groupNames;
43+
if (isGroup) {
44+
this.groupType = ((GroupItemDTO) itemDTO).groupType;
45+
this.function = ((GroupItemDTO) itemDTO).function;
46+
}
47+
}
48+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright (c) 2010-2025 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.core.io.rest.core.fileformat;
14+
15+
import java.util.ArrayList;
16+
import java.util.Collection;
17+
import java.util.LinkedHashMap;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.Objects;
21+
22+
import org.eclipse.jdt.annotation.NonNullByDefault;
23+
import org.eclipse.jdt.annotation.Nullable;
24+
import org.openhab.core.items.GroupItem;
25+
import org.openhab.core.items.Item;
26+
import org.openhab.core.items.ItemBuilderFactory;
27+
import org.openhab.core.items.Metadata;
28+
import org.openhab.core.items.MetadataKey;
29+
import org.openhab.core.items.dto.GroupItemDTO;
30+
import org.openhab.core.items.dto.ItemDTO;
31+
import org.openhab.core.items.dto.ItemDTOMapper;
32+
import org.openhab.core.items.dto.MetadataDTO;
33+
import org.openhab.core.thing.link.ItemChannelLink;
34+
35+
/**
36+
* The {@link FileFormatItemDTOMapper} is a utility class to map items into file format item data transfer objects
37+
* (DTOs).
38+
*
39+
* @author Laurent Garnier - Initial contribution
40+
*/
41+
@NonNullByDefault
42+
public class FileFormatItemDTOMapper {
43+
44+
/**
45+
* Maps item into file format item DTO object.
46+
*
47+
* @param item the item
48+
* @param metadata some metadata
49+
* @param format the format to be used to format the item state, can be NULL
50+
* @param channelLinks some items channel links
51+
* @return file format item DTO object
52+
*/
53+
public static FileFormatItemDTO map(Item item, Collection<Metadata> metadata, @Nullable String format,
54+
Collection<ItemChannelLink> channelLinks) {
55+
ItemDTO itemDto = ItemDTOMapper.map(item);
56+
FileFormatItemDTO dto = new FileFormatItemDTO(itemDto, itemDto instanceof GroupItemDTO);
57+
58+
dto.format = format;
59+
60+
Map<String, MetadataDTO> metadataDTO = new LinkedHashMap<>();
61+
metadata.forEach(md -> {
62+
if (item.getName().equals(md.getUID().getItemName())) {
63+
MetadataDTO mdDTO = new MetadataDTO();
64+
mdDTO.value = md.getValue();
65+
mdDTO.config = md.getConfiguration().isEmpty() ? null : md.getConfiguration();
66+
metadataDTO.put(md.getUID().getNamespace(), mdDTO);
67+
}
68+
});
69+
if (!metadataDTO.isEmpty()) {
70+
dto.metadata = metadataDTO;
71+
}
72+
73+
List<FileFormatChannelLinkDTO> channelLinksDTO = new ArrayList<>();
74+
channelLinks.forEach(link -> {
75+
if (item.getName().equals(link.getItemName())) {
76+
channelLinksDTO.add(new FileFormatChannelLinkDTO(link.getLinkedUID().getAsString(),
77+
link.getConfiguration().getProperties().isEmpty() ? null
78+
: link.getConfiguration().getProperties()));
79+
}
80+
});
81+
if (!channelLinksDTO.isEmpty()) {
82+
dto.channelLinks = channelLinksDTO;
83+
}
84+
85+
return dto;
86+
}
87+
88+
/**
89+
* Maps file format item DTO object into item.
90+
*
91+
* @param dto the file format item DTO object
92+
* @param itemBuilderFactory the item builder factory
93+
* @return item
94+
*/
95+
public static @Nullable Item map(FileFormatItemDTO dto, ItemBuilderFactory itemBuilderFactory) {
96+
if (GroupItem.TYPE.equals(dto.type)) {
97+
GroupItemDTO groupDto = new GroupItemDTO();
98+
groupDto.type = dto.type;
99+
groupDto.name = dto.name;
100+
groupDto.label = dto.label;
101+
groupDto.category = dto.category;
102+
groupDto.tags = dto.tags;
103+
groupDto.groupNames = dto.groupNames;
104+
groupDto.groupType = dto.groupType;
105+
groupDto.function = dto.function;
106+
return ItemDTOMapper.map(groupDto, itemBuilderFactory);
107+
}
108+
return ItemDTOMapper.map(dto, itemBuilderFactory);
109+
}
110+
111+
/**
112+
* Maps file format item DTO object into a collection of metadata including channels links
113+
* provided through the "channel" namespace.
114+
*
115+
* @param dto the file format item DTO object
116+
* @return the collection of metadata
117+
*/
118+
public static Collection<Metadata> mapMetadata(FileFormatItemDTO dto) {
119+
String name = dto.name;
120+
Collection<Metadata> metadata = new ArrayList<>();
121+
if (dto.channelLinks != null) {
122+
for (FileFormatChannelLinkDTO link : dto.channelLinks) {
123+
MetadataKey key = new MetadataKey("channel", name);
124+
metadata.add(new Metadata(key, link.channelUID, link.configuration));
125+
}
126+
}
127+
if (dto.metadata != null) {
128+
for (Map.Entry<String, MetadataDTO> md : dto.metadata.entrySet()) {
129+
MetadataKey key = new MetadataKey(md.getKey(), name);
130+
metadata.add(new Metadata(key, Objects.requireNonNull(md.getValue().value), md.getValue().config));
131+
}
132+
}
133+
return metadata;
134+
}
135+
}

0 commit comments

Comments
 (0)