1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tools.gsf.properties;
17
18 import COM.FutureTense.Interfaces.ICS;
19 import COM.FutureTense.Interfaces.ISyncHash;
20 import COM.FutureTense.Util.ftErrors;
21 import com.fatwire.assetapi.common.AssetAccessException;
22 import com.fatwire.assetapi.common.SiteAccessException;
23 import com.fatwire.assetapi.data.AssetData;
24 import com.fatwire.assetapi.data.AssetDataManager;
25 import com.fatwire.assetapi.data.AssetId;
26 import com.fatwire.assetapi.data.AttributeData;
27 import com.fatwire.assetapi.data.MutableAssetData;
28 import com.fatwire.assetapi.query.OpTypeEnum;
29 import com.fatwire.assetapi.query.Query;
30 import com.fatwire.assetapi.site.SiteInfo;
31 import com.fatwire.assetapi.site.SiteManager;
32 import tools.gsf.facade.assetapi.AttributeDataUtils;
33 import tools.gsf.facade.assetapi.QueryBuilder;
34 import tools.gsf.facade.runtag.render.LogDep;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import tools.gsf.runtime.CSRuntimeException;
38
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.HashSet;
44
45
46
47
48
49
50
51
52
53
54 public final class AssetApiPropertyDao implements PropertyDao {
55 private static final Logger LOG = LoggerFactory.getLogger("tools.gsf.properties.AssetApiPropertyDao");
56 private static final int TIMEOUT_MINUTES = 60 * 24;
57 private static final int MAX_SIZE = 1000000;
58 private static final String ID = "id";
59 private static final String PUBLIST = "Publist";
60
61 private final ISyncHash _props;
62 private final AssetDataManager assetDataManager;
63 private final SiteManager siteManager;
64 private final String assetType;
65 private final String assetFlexDefinition;
66 private final String propertyNameAttr;
67 private final String propertyDescriptionAttr;
68 private final String propertyValueAttr;
69 private final ICS _ics;
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public AssetApiPropertyDao(AssetDataManager adm, SiteManager siteManager, String type, String flexDefName, String propNameAttr, String propDescAttr, String propValueAttr, ICS ics) {
85 this.assetDataManager = adm;
86 this.siteManager = siteManager;
87 this.assetType = type;
88 this.assetFlexDefinition = flexDefName;
89 this.propertyNameAttr = propNameAttr;
90 this.propertyDescriptionAttr = propDescAttr;
91 this.propertyValueAttr = propValueAttr;
92 this._props = ics.GetSynchronizedHash(AssetApiPropertyDao.class.getName(), true, TIMEOUT_MINUTES, MAX_SIZE, true, true, Collections.singletonList(ics.GetProperty("cs.dsn") + assetType));
93 this._ics = ics;
94 }
95
96 public synchronized Property getProperty(String name) {
97 PropertyHolder ph = (PropertyHolder) _props.get(name);
98 if (ph == null) {
99 ph = _readProperty(name);
100 _props.put(name, ph);
101 }
102 if (ph.getId() != null) {
103 LogDep.logDep(_ics, ph.getId());
104 }
105 return ph.getProp();
106 }
107
108 @SuppressWarnings("unchecked")
109 public synchronized Collection<String> getPropertyNames() {
110 ArrayList<String> keys = new ArrayList<>();
111 for (Object key : _props.keySet()) {
112 String sKey = (String) key;
113 PropertyHolder ph = (PropertyHolder) _props.get(sKey);
114 if (ph != PropertyHolder.EMPTY_HOLDER) {
115 keys.add(sKey);
116 }
117 }
118 return keys;
119 }
120
121 private PropertyHolder _readProperty(String name) {
122 Query loadQuery = new QueryBuilder(assetType, assetFlexDefinition).attributes(ID, propertyNameAttr, propertyDescriptionAttr, propertyValueAttr)
123 .condition("status", OpTypeEnum.NOT_EQUALS, "VO")
124 .condition(propertyNameAttr, OpTypeEnum.EQUALS, name)
125 .setBasicSearch(true)
126 .setFixedList(true)
127 .toQuery();
128 try {
129 for (AssetData propData : assetDataManager.read(loadQuery)) {
130 AttributeData oName = propData.getAttributeData(propertyNameAttr);
131 AttributeData oDesc = propData.getAttributeData(propertyDescriptionAttr);
132 AttributeData oVal = propData.getAttributeData(propertyValueAttr);
133 AssetId id = propData.getAssetId();
134 if (oName == null) {
135 throw new IllegalStateException("Property name attribute configured in PropertyDao not found in asset: " + propertyNameAttr);
136 }
137 if (oDesc == null) {
138 throw new IllegalStateException("Property description attribute configured in PropertyDao not found in asset" + propertyDescriptionAttr);
139 }
140 if (oVal == null) {
141 throw new IllegalStateException("Property value attribute configured in PropertyDao not found in asset" + propertyValueAttr);
142 }
143 LOG.debug("Loaded property {}", name);
144 return new PropertyHolder(name, AttributeDataUtils.asString(oDesc), AttributeDataUtils.asString(oVal), id);
145 }
146 } catch (AssetAccessException e) {
147 LOG.error("Failure reading property: {}", name, e);
148 return AssetApiPropertyDao.PropertyHolder.EMPTY_HOLDER;
149 }
150 LOG.debug("Property not found: {}", name);
151 return AssetApiPropertyDao.PropertyHolder.EMPTY_HOLDER;
152 }
153
154
155
156
157
158
159
160
161 public synchronized void setProperty(String name, String description, String value) {
162 if (name == null) {
163 throw new IllegalArgumentException("Cannot set a null property name");
164 }
165
166 String pubid = _ics.GetSSVar("pubid");
167 String site = _lookupSiteName(pubid);
168
169 PropertyHolder holder = _readProperty(name);
170 if (holder == PropertyHolder.EMPTY_HOLDER) {
171
172 try {
173 MutableAssetData data = assetDataManager.newAssetData(assetType, assetFlexDefinition);
174 data.getAttributeData(propertyNameAttr).setData(name);
175 data.getAttributeData(propertyDescriptionAttr).setData(description);
176 data.getAttributeData(propertyValueAttr).setData(value);
177 _appendToPublist(data.getAttributeData(PUBLIST), site);
178 assetDataManager.insert(Collections.singletonList(data));
179 holder = new PropertyHolder(name, description, value, data.getAssetId());
180 } catch (AssetAccessException e) {
181 throw new CSRuntimeException("Could not add new property " + name, ftErrors.exceptionerr, e);
182 }
183 } else {
184
185 try {
186 ArrayList<AssetData> sAssets = new ArrayList<>();
187 for (MutableAssetData data : assetDataManager.readForUpdate(Collections.singletonList(holder.getId()))) {
188
189 data.getAttributeData(propertyDescriptionAttr).setData(description);
190 data.getAttributeData(propertyValueAttr).setData(value);
191 _appendToPublist(data.getAttributeData(PUBLIST), site);
192 sAssets.add(data);
193 holder = new PropertyHolder(name, description, value, holder.getId());
194 }
195 assetDataManager.update(sAssets);
196 } catch (AssetAccessException e) {
197 throw new CSRuntimeException("Could not update property " + name, ftErrors.exceptionerr, e);
198 }
199 }
200
201 _props.put(name, holder);
202 }
203
204
205
206
207
208
209 public synchronized void setProperty(Property property) {
210 if (property == null) {
211 throw new IllegalArgumentException("Can't set a null property object");
212 }
213 setProperty(property.getName(), property.getDescription(), property.asString());
214 }
215
216 @SuppressWarnings("unchecked")
217 private void _appendToPublist(AttributeData data, String... siteName) {
218 if (siteName != null) {
219 HashSet<String> pubs = new HashSet<>();
220 pubs.addAll(Arrays.asList(siteName));
221 pubs.addAll(data.getDataAsList());
222 data.setDataAsList(new ArrayList<>(pubs));
223 }
224 }
225
226 private String _lookupSiteName(String pubid) {
227 if (pubid != null) {
228 long id = Long.valueOf(pubid);
229 try {
230 for (SiteInfo si : siteManager.list()) {
231 if (si.getId() == id) {
232 return si.getName();
233 }
234 }
235 } catch (SiteAccessException e) {
236 throw new CSRuntimeException("Could not determine name of current site: " + e, ftErrors.exceptionerr, e);
237 }
238 }
239 return null;
240 }
241
242 @SuppressWarnings({"unchecked", "rawtypes"})
243 public synchronized void addToSite(String name, String... site) {
244 if (name == null) {
245 throw new IllegalArgumentException("Invalid property name null");
246 }
247 PropertyHolder holder = _readProperty(name);
248 if (holder == PropertyHolder.EMPTY_HOLDER) {
249 throw new IllegalArgumentException("Could not locate property " + name);
250 }
251
252 try {
253 ArrayList<AssetData> sAssets = new ArrayList<>();
254 for (MutableAssetData data : assetDataManager.readForUpdate(Collections.singletonList(holder.getId()))) {
255 AttributeData publistData = data.getAttributeData(PUBLIST);
256 _appendToPublist(publistData, site);
257 sAssets.add(data);
258 }
259 assetDataManager.update(sAssets);
260 } catch (AssetAccessException e) {
261 throw new CSRuntimeException("Failure adding property " + name + " to sites " + Arrays.asList(site), ftErrors.exceptionerr, e);
262 }
263 }
264
265 private static class PropertyHolder {
266
267 private static final PropertyHolder EMPTY_HOLDER = new PropertyHolder();
268 private final Property prop;
269 private final AssetId id;
270
271
272
273
274 private PropertyHolder() {
275 prop = null;
276 id = null;
277 }
278
279
280
281
282
283
284
285
286
287 private PropertyHolder(String name, String description, String value, AssetId id) {
288 if (name == null) {
289 throw new IllegalArgumentException("Null name not allowed");
290 }
291 if (value == null) {
292 throw new IllegalArgumentException("Null value not allowed");
293 }
294 this.id = id;
295 this.prop = new PropertyImpl(id.getType(), name, description, value);
296 }
297
298 private Property getProp() {
299 return prop;
300 }
301
302 private AssetId getId() {
303 return id;
304 }
305 }
306 }