1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package tools.gsf.facade.mda;
18
19 import COM.FutureTense.Interfaces.FTValList;
20 import COM.FutureTense.Interfaces.ICS;
21 import COM.FutureTense.Interfaces.IList;
22 import COM.FutureTense.Util.IterableIListWrapper;
23 import COM.FutureTense.Util.ftErrors;
24 import com.fatwire.assetapi.data.AssetId;
25 import com.fatwire.cs.core.db.PreparedStmt;
26 import com.fatwire.cs.core.db.StatementParam;
27 import com.fatwire.mda.Dimension;
28 import com.fatwire.mda.DimensionException;
29 import com.fatwire.mda.DimensionFilterInstance;
30 import com.fatwire.mda.DimensionManager;
31 import com.fatwire.mda.DimensionSetInstance;
32 import com.fatwire.mda.DimensionableAssetManager;
33 import com.fatwire.system.Session;
34 import com.openmarket.xcelerate.asset.AssetIdImpl;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import tools.gsf.facade.runtag.asset.AssetLoadByName;
38 import tools.gsf.facade.runtag.render.LogDep;
39 import tools.gsf.facade.sql.IListUtils;
40 import tools.gsf.runtime.CSRuntimeException;
41
42 import java.util.Arrays;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.List;
46
47
48
49
50
51
52
53
54 public final class LocaleUtils {
55 private static final Logger _log = LoggerFactory.getLogger("tools.gsf.facade.mda.LocaleUtils");
56
57 private LocaleUtils() {
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public static AssetId findTranslation(ICS ics, String c, String cid, String preferredLocaleDimensionId, String site) {
80 return findTranslation(ics, new AssetIdImpl(c, Long.valueOf(cid)), preferredLocaleDimensionId, site);
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public static AssetId findTranslation(ICS ics, AssetId id, String preferredLocaleDimensionIdString, String site) {
103 if (preferredLocaleDimensionIdString == null) {
104 throw new IllegalArgumentException("Required preferred locale dimension ID not provided");
105 }
106 long preferredDimension = Long.valueOf(preferredLocaleDimensionIdString);
107
108 long dimensionSetId = locateDimensionSetForSite(ics, site);
109
110 return findTranslation(ics, id, preferredDimension, dimensionSetId);
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 public static AssetId findTranslation(ICS ics, AssetId id, long preferredDimension, long dimensionSetId) {
133 if (id == null) {
134 throw new IllegalArgumentException("Required Asset ID missing");
135 }
136
137 DimensionableAssetManager mgr = DimensionUtils.getDAM(ics);
138
139 if (_isInputAssetDimensionPreferred(mgr, id, preferredDimension)) {
140 _log.debug("Input dimension is already in the preferred dimension. Not invoking dimension set filter. Asset: "
141 + id + ", dimension: " + preferredDimension);
142 return id;
143 } else {
144 _log.debug("About to look for translations. Input asset id: " + id + ", dimension set: " + dimensionSetId
145 + ", preferred dimension: " + preferredDimension);
146 }
147
148
149
150
151 DimensionSetInstance dimset = getDimensionSet(ics, dimensionSetId);
152 return findTranslation(ics, id, preferredDimension, dimset);
153
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public static AssetId findTranslation(ICS ics, AssetId id, long preferredDimension, String dimensionSetName) {
179 if (id == null) {
180 throw new IllegalArgumentException("Required Asset ID missing");
181 }
182 Dimension locale = DimensionUtils.getLocaleAsDimension(ics, id);
183
184 if (locale == null) {
185 _log.debug("Asset is not localized. Not invoking dimension set filter. Asset: " + id);
186 return id;
187 }
188 if (locale.getId().getId() == preferredDimension) {
189 _log.debug("Input dimension is already in the preferred dimension. Not invoking dimension set filter. Asset: "
190 + id + ", dimension: " + preferredDimension);
191 return id;
192 } else {
193 _log.debug("About to look for translations. Input asset id: " + id + ", dimension set: "
194 + dimensionSetName + ", preferred dimension: " + preferredDimension);
195 }
196
197
198
199
200 DimensionSetInstance dimset = getDimensionSet(ics, dimensionSetName);
201
202 return findTranslation(ics, id, preferredDimension, dimset);
203 }
204
205
206
207
208
209
210
211
212
213 public static AssetId findTranslation(ICS ics, AssetId id, long preferredDimension, DimensionSetInstance dimset)
214 throws IllegalStateException {
215 AssetId preferredDim = new AssetIdImpl("Dimension", preferredDimension);
216 List<AssetId> preferredDims = Collections.singletonList(preferredDim);
217 Collection<AssetId> relatives = findTranslation(DimensionUtils.getDM(ics), Collections.singletonList(id), preferredDims, dimset);
218
219
220
221 if (relatives == null) {
222 _log.warn("No translation found for asset " + id + " in dimension set " + dimset.getId()
223 + " for dimension " + preferredDimension + ".");
224 return null;
225 } else {
226 switch (relatives.size()) {
227 case 0: {
228 _log.warn("No translation found for " + id + " in dimension set " + dimset.getId()
229 + " for dimension " + preferredDimension + ".");
230
231
232
233
234
235
236
237 return null;
238 }
239 case 1: {
240 AssetId relative = relatives.iterator().next();
241 _log.trace("LocaleUtils.findTranslation: RELATIVE FOUND... " + relative.getType() + " '"
242 + relative.getId() + "' // errno = " + ics.GetErrno());
243 return relative;
244
245 }
246 default: {
247 throw new IllegalStateException("found more than one translation for asset " + id
248 + " and that is not supposed to be possible.");
249 }
250 }
251 }
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public static Collection<AssetId> findTranslation(DimensionManager dimensionManager, List<AssetId> toFilterList, Collection<AssetId> preferredDimensionIds, DimensionSetInstance dimSet) {
267 try {
268 return DimensionUtils.filterAssets(dimensionManager, toFilterList, preferredDimensionIds, dimSet);
269 } catch (DimensionException e) {
270 throw new CSRuntimeException("Failed to translate assets. Input assets:" + toFilterList + ", Preferred Dimensions: " + preferredDimensionIds + ", DimensionSet:" + dimSet, ftErrors.exceptionerr, e);
271 }
272 }
273
274
275
276
277 private static boolean _isInputAssetDimensionPreferred(DimensionableAssetManager mgr, AssetId id,
278 long preferredDimension) {
279 Dimension dim = DimensionUtils.getLocaleAsDimension(mgr, id);
280 if (dim == null) {
281 return true;
282 }
283
284 return dim.getId().getId() == preferredDimension;
285 }
286
287 private static final PreparedStmt FIND_DIMSET_FOR_SITE_PREPAREDSTMT = new PreparedStmt(
288 "select ds.id as id from DimensionSet ds, Publication p, AssetPublication ap where p.name = ? and p.id = ap.pubid and ap.assetid = ds.id and ds.status != 'VO' order by ds.updateddate",
289 Arrays.asList("DimensionSet", "AssetPublication", "Publication"));
290
291 static {
292 FIND_DIMSET_FOR_SITE_PREPAREDSTMT.setElement(0, "Publication", "name");
293 }
294
295
296
297
298
299
300
301
302
303
304 public static long locateDimensionSetForSite(ICS ics, String site) {
305 if (site == null) {
306 throw new IllegalArgumentException("Required site name missing");
307 }
308 StatementParam params = FIND_DIMSET_FOR_SITE_PREPAREDSTMT.newParam();
309 params.setString(0, site);
310 IList results = ics.SQL(FIND_DIMSET_FOR_SITE_PREPAREDSTMT, params, true);
311 int numRows = results != null && results.hasData() ? results.numRows() : 0;
312 if (numRows == 0) {
313 throw new IllegalStateException(
314 "A DimensionSet has not been defined for site '"
315 + site
316 + "'. Cannot determine any translation unless some locales (Dimensions) are enabled for that site. Aborting operation.");
317 }
318 if (numRows > 1) {
319 String msg = "More than one dimension set found in site " + site
320 + ". Exactly one is expected. Dimension set ids: ";
321 for (IList row : new IterableIListWrapper(results)) {
322 String id = IListUtils.getStringValue(row, "id");
323 LogDep.logDep(ics, "DimensionSet", id);
324 msg += id + " ";
325 }
326 throw new IllegalStateException(msg + ".");
327 }
328 results.moveTo(1);
329 String id = IListUtils.getStringValue(results, "id");
330 LogDep.logDep(ics, "DimensionSet", id);
331 if (_log.isTraceEnabled()) {
332 _log.trace("Looked up dimset for site " + site + " and found " + id);
333 }
334 return Long.valueOf(id);
335 }
336
337 private static DimensionFilterInstance _getPopulatedDimensionFilter(Session ses, DimensionSetInstance dimset,
338 long localeDimensionId) {
339
340
341
342
343
344 Dimension thePreferredDimension = ((DimensionManager) ses.getManager(DimensionManager.class.getName()))
345 .loadDimension(localeDimensionId);
346 if (thePreferredDimension == null) {
347 throw new RuntimeException("Attempted to load Dimension with id " + localeDimensionId
348 + " but it came back null");
349 }
350 return _getPopulatedDimensionFilter(dimset, thePreferredDimension);
351 }
352
353 private static DimensionFilterInstance _getPopulatedDimensionFilter(DimensionSetInstance dimset,
354 Dimension preferredDimension) {
355 DimensionFilterInstance filter;
356 try {
357 filter = dimset.getFilter();
358 } catch (DimensionException e) {
359 throw new RuntimeException("Could not get Dimension Filter from DimensionSet", e);
360 }
361
362 filter.setDimensonPreference(Collections.singletonList(preferredDimension));
363 return filter;
364 }
365
366 public static DimensionSetInstance getDimensionSet(ICS ics, long theDimSetId) {
367 final String DIMSET_OBJ_NAME = "LocaleUtils:findTranslation:theDimensionSet:DimensionSet";
368
369
370 ics.SetObj(DIMSET_OBJ_NAME, null);
371 FTValList args = new FTValList();
372 args.put("NAME", DIMSET_OBJ_NAME);
373 args.put("TYPE", "DimensionSet");
374 args.put("OBJECTID", Long.toString(theDimSetId));
375 args.put("EDITABLE", "FALSE");
376 ics.runTag("ASSET.LOAD", args);
377
378 if (ics.GetErrno() < 0) {
379 throw new IllegalStateException("Could not load dimension set. Errno: " + ics.GetErrno());
380 }
381
382 Object o = ics.GetObj(DIMSET_OBJ_NAME);
383 if (o == null) {
384 throw new IllegalStateException("Could not load dimension set but we got no errno... unexpected...");
385 }
386
387 DimensionSetInstance dimset;
388 if (o instanceof DimensionSetInstance) {
389 dimset = (DimensionSetInstance) o;
390 } else {
391 throw new IllegalStateException("Loaded an asset that is not a Dimension Set");
392 }
393 return dimset;
394 }
395
396 public static DimensionSetInstance getDimensionSet(ICS ics, String name) {
397 final String DIMSET_OBJ_NAME = "LocaleUtils:findTranslation:theDimensionSet:DimensionSet";
398 ics.SetObj(DIMSET_OBJ_NAME, null);
399 AssetLoadByName a = new AssetLoadByName();
400 a.setAssetType("DimensionSet");
401 a.setAssetName(name);
402 a.setEditable(false);
403 a.setName(DIMSET_OBJ_NAME);
404 a.execute(ics);
405
406 if (ics.GetErrno() < 0) {
407 throw new IllegalStateException("Could not load dimension set. Errno: " + ics.GetErrno());
408 }
409
410 Object o = ics.GetObj(DIMSET_OBJ_NAME);
411 ics.SetObj(DIMSET_OBJ_NAME, null);
412 if (o == null) {
413 throw new IllegalStateException("Could not load dimension set but we got no errno... unexpected...");
414 }
415
416 DimensionSetInstance dimset;
417 if (o instanceof DimensionSetInstance) {
418 dimset = (DimensionSetInstance) o;
419 } else {
420 throw new IllegalStateException("Loaded an asset that is not a Dimension Set");
421 }
422 return dimset;
423 }
424
425 }