1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.fatwire.gst.foundation.tagging.db;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.Date;
22 import java.util.HashSet;
23 import java.util.List;
24
25 import COM.FutureTense.Cache.CacheHelper;
26 import COM.FutureTense.Cache.CacheManager;
27 import COM.FutureTense.Interfaces.ICS;
28
29 import com.fatwire.assetapi.data.AssetData;
30 import com.fatwire.assetapi.data.AssetId;
31 import com.fatwire.cs.core.db.PreparedStmt;
32 import com.fatwire.cs.core.db.StatementParam;
33 import com.fatwire.gst.foundation.facade.assetapi.AssetAccessTemplate;
34 import com.fatwire.gst.foundation.facade.assetapi.AssetMapper;
35 import com.fatwire.gst.foundation.facade.assetapi.AttributeDataUtils;
36 import com.fatwire.gst.foundation.facade.assetapi.DirectSqlAccessTools;
37 import com.fatwire.gst.foundation.facade.cm.AddRow;
38 import com.fatwire.gst.foundation.facade.logging.LogUtil;
39 import com.fatwire.gst.foundation.facade.runtag.asset.FilterAssetsByDate;
40 import com.fatwire.gst.foundation.facade.runtag.render.LogDep;
41 import com.fatwire.gst.foundation.facade.sql.Row;
42 import com.fatwire.gst.foundation.facade.sql.SqlHelper;
43 import com.fatwire.gst.foundation.facade.sql.table.TableColumn;
44 import com.fatwire.gst.foundation.facade.sql.table.TableCreator;
45 import com.fatwire.gst.foundation.facade.sql.table.TableDef;
46 import com.fatwire.gst.foundation.tagging.AssetTaggingService;
47 import com.fatwire.gst.foundation.tagging.Tag;
48 import com.openmarket.xcelerate.asset.AssetIdImpl;
49
50 import org.apache.commons.lang.StringUtils;
51 import org.apache.commons.logging.Log;
52
53 import static com.fatwire.gst.foundation.tagging.TagUtils.asTag;
54 import static com.fatwire.gst.foundation.tagging.TagUtils.convertTagToCacheDepString;
55
56
57
58
59
60
61
62 public final class TableTaggingServiceImpl implements AssetTaggingService {
63
64 private static final Log LOG = LogUtil.getLog(TableTaggingServiceImpl.class);
65
66 public static String TAGREGISTRY_TABLE = "GSTTagRegistry";
67 public static String TABLE_ACL_LIST = "";
68
69
70 private final ICS ics;
71 private final DirectSqlAccessTools directSqlAccessTools;
72
73 public TableTaggingServiceImpl(ICS ics) {
74 this.ics = ics;
75 this.directSqlAccessTools = new DirectSqlAccessTools(ics);
76 }
77
78 public void install() {
79 TableDef def = new TableDef(TAGREGISTRY_TABLE, TABLE_ACL_LIST, "obj");
80
81
82 def.addColumn("tag", TableColumn.Type.ccvarchar).setLength(255).setNullable(false);
83 def.addColumn("assettype", TableColumn.Type.ccvarchar).setLength(255).setNullable(false);
84 def.addColumn("assetid", TableColumn.Type.ccbigint).setNullable(false);
85 def.addColumn("startdate", TableColumn.Type.ccdatetime).setNullable(true);
86 def.addColumn("enddate", TableColumn.Type.ccdatetime).setNullable(true);
87
88 new TableCreator(ics).createTable(def);
89 }
90
91 public boolean isInstalled() {
92 return SqlHelper.tableExists(ics, TAGREGISTRY_TABLE);
93 }
94
95 public void recordCacheDependency(Tag tag) {
96 CacheManager.RecordItem(ics, convertTagToCacheDepString(tag));
97 }
98
99 public void clearCacheForTag(Collection<Tag> tags) {
100 List<String> ids = new ArrayList<String>();
101 for (Tag tag : tags) {
102 ids.add(convertTagToCacheDepString(tag));
103 }
104 CacheManager cm = new CacheManager(ics);
105 cm.setPagesByID(ics, ids.toArray(new String[ids.size()]));
106 cm.flushCSEngine(ics, CacheHelper._both);
107 cm.flushSSEngines(ics);
108 }
109
110 public void addAsset(AssetId id) {
111
112
113 TaggedAsset asset = loadTaggedAsset(id);
114 if (isTagged(asset)) {
115 if (LOG.isTraceEnabled()) {
116 LOG.trace("Adding tagged asset to tag registry: " + asset);
117 }
118 for (Tag tag : asset.getTags()) {
119
120 AddRow r = new AddRow(TAGREGISTRY_TABLE);
121
122 r.set("id", ics.genID(true));
123 r.set("tag", tag.getTag());
124 r.set("assettype", id.getType());
125 r.set("assetid", id.getId());
126 r.set("startdate", asset.getStartDate());
127 r.set("enddate", asset.getEndDate());
128 r.execute(ics);
129 }
130 }
131 }
132
133 public void updateAsset(AssetId id) {
134
135 deleteAsset(id);
136 addAsset(id);
137 }
138
139 public void deleteAsset(AssetId id) {
140 if (LOG.isTraceEnabled()) {
141 LOG.trace("Attempting to remove asset from tag registry:" + id);
142 }
143 SqlHelper.execute(
144 ics,
145 TAGREGISTRY_TABLE,
146 "DELETE FROM " + TAGREGISTRY_TABLE + " WHERE assettype = '" + id.getType() + "' and assetid = "
147 + id.getId());
148 if (LOG.isDebugEnabled()) {
149 LOG.debug("Deleted tagged asset " + id + " from tag registry (or asset was never there in the first place)");
150 }
151 }
152
153 public Collection<Tag> getTags(AssetId id) {
154
155
156 return loadTaggedAsset(id).getTags();
157 }
158
159 public Collection<Tag> getTags(Collection<AssetId> ids) {
160 HashSet<Tag> tags = new HashSet<Tag>();
161
162
163 if (ids.size() > 5)
164 LOG.warn("Fetching tags serially for " + ids.size()
165 + " assets. TableTaggingServiceImpl isn't yet optimized to handle this very nicely");
166 for (AssetId id : ids) {
167 tags.addAll(getTags(id));
168 }
169 return tags;
170 }
171
172
173
174
175
176
177
178
179 private TaggedAsset loadTaggedAsset(AssetId id) {
180 LogDep.logDep(ics, id);
181
182
183
184
185
186 final TaggedAsset ret;
187 final String gsttagAttrVal;
188 if (directSqlAccessTools.isFlex(id)) {
189 PreparedStmt basicFields = new PreparedStmt("SELECT id,startdate,enddate" + " FROM " + id.getType()
190 + " WHERE id = ?", Collections.singletonList(id.getType()));
191 basicFields.setElement(0, id.getType(), "id");
192
193 StatementParam param = basicFields.newParam();
194 param.setLong(0, id.getId());
195 Row row = SqlHelper.selectSingle(ics, basicFields, param);
196
197 Date start = StringUtils.isBlank(row.getString("startdate")) ? null : row.getDate("startdate");
198 Date end = StringUtils.isBlank(row.getString("enddate")) ? null : row.getDate("enddate");
199 ret = new TaggedAsset(id, start, end);
200
201
202 gsttagAttrVal = directSqlAccessTools.getFlexAttributeValue(id, "gsttag");
203
204 } else {
205
206 PreparedStmt basicFields = new PreparedStmt("SELECT * FROM " + id.getType() + " WHERE ID = ?",
207 Collections.singletonList(id.getType()));
208 basicFields.setElement(0, id.getType(), "id");
209
210 StatementParam param = basicFields.newParam();
211 param.setLong(0, id.getId());
212 Row row = SqlHelper.selectSingle(ics, basicFields, param);
213
214 Date start = StringUtils.isBlank(row.getString("startdate")) ? null : row.getDate("startdate");
215 Date end = StringUtils.isBlank(row.getString("enddate")) ? null : row.getDate("enddate");
216 ret = new TaggedAsset(id, start, end);
217 String s = "";
218 try {
219 if (row.isField("gsttag")) {
220 s = row.getString("gsttag");
221 }
222 } catch (Exception e) {
223 LOG.trace("Could not get gsttag data from basic asset. Maybe this is just because "
224 + "there is no gsttag column - which is just fine.", e);
225 }
226 gsttagAttrVal = s;
227 }
228
229 if (StringUtils.isNotBlank(gsttagAttrVal)) {
230 for (String tag : gsttagAttrVal.split(",")) {
231 Tag oTag = asTag(tag);
232 recordCacheDependency(oTag);
233 ret.addTag(oTag);
234 }
235 }
236
237
238
239 if (LOG.isTraceEnabled())
240 LOG.trace("Loaded tagged asset " + ret);
241 return ret;
242 }
243
244 private AssetMapper<TaggedAsset> mapper = new AssetMapper<TaggedAsset>() {
245
246 public TaggedAsset map(AssetData data) {
247 Date startDate = AttributeDataUtils.asDate(data.getAttributeData("startdate"));
248 Date endDate = AttributeDataUtils.asDate(data.getAttributeData("enddate"));
249 TaggedAsset ret = new TaggedAsset(data.getAssetId(), startDate, endDate);
250 for (String tag : AttributeDataUtils.getAndSplitString(data.getAttributeData("gsttag"), ",")) {
251 Tag oTag = asTag(tag);
252
253 ret.addTag(oTag);
254 }
255
256 return ret;
257 }
258
259 };
260
261
262
263
264
265
266
267
268
269 @SuppressWarnings("unused")
270 private TaggedAsset loadTaggedAssetNew(AssetId id) {
271 LogDep.logDep(ics, id);
272 AssetAccessTemplate aat = new AssetAccessTemplate(ics);
273 TaggedAsset ret = aat.readAsset(id, mapper, "startdate", "enddate", "gsttag");
274
275 for (Tag tag : ret.getTags()) {
276 recordCacheDependency(tag);
277 }
278 if (LOG.isTraceEnabled())
279 LOG.trace("Loaded tagged asset " + ret);
280 return ret;
281 }
282
283 public Collection<AssetId> lookupTaggedAssets(Tag tag) {
284 recordCacheDependency(tag);
285 final StatementParam param = REGISTRY_SELECT.newParam();
286 param.setString(0, tag.getTag());
287 List<AssetId> ids = new ArrayList<AssetId>();
288 for (final Row asset : SqlHelper.select(ics, REGISTRY_SELECT, param)) {
289 AssetId id = new AssetIdImpl(asset.getString("assettype"), asset.getLong("assetid"));
290 LogDep.logDep(ics, id);
291 if (FilterAssetsByDate.isValidOnDate(ics, id, null)) {
292 ids.add(id);
293 } else {
294 if (LOG.isDebugEnabled())
295 LOG.debug("Asset " + id + " tagged with " + tag + " is not active based on startdate/enddate");
296 }
297 }
298 return ids;
299 }
300
301 public boolean isTagged(AssetId id) {
302 TaggedAsset ta = loadTaggedAsset(id);
303 return isTagged(ta);
304 }
305
306 public boolean isTagged(TaggedAsset ta) {
307 if (ta == null)
308 return false;
309 try {
310 if (ta.getTags().size() > 0) {
311 if (LOG.isTraceEnabled()) {
312 LOG.trace("isTagged loaded the asset and found that " + ta.getId() + " is a tagged asset.");
313 }
314 return true;
315 } else {
316 if (LOG.isTraceEnabled()) {
317 LOG.trace("isTagged loaded the asset and found that " + ta.getId() + " is not a tagged asset.");
318 }
319 return false;
320 }
321 } catch (RuntimeException e) {
322 if (LOG.isTraceEnabled()) {
323 LOG.trace(
324 "isTagged found that " + ta.getId() + " is not a tagged asset. We found an exception: " + e.toString(),
325 e);
326 }
327 return false;
328 }
329 }
330
331 private static final PreparedStmt REGISTRY_SELECT = new PreparedStmt(
332 "SELECT tag, assettype, assetid, startdate, enddate " + "FROM " + TAGREGISTRY_TABLE
333 + " WHERE tag=? ORDER BY startdate,enddate", Collections.singletonList(TAGREGISTRY_TABLE));
334
335 static {
336 REGISTRY_SELECT.setElement(0, TAGREGISTRY_TABLE, "tag");
337 }
338
339 private static class TaggedAsset {
340 final AssetId id;
341 final Date startDate;
342 final Date endDate;
343 final Collection<Tag> tags;
344
345 TaggedAsset(AssetId id, Date startDate, Date endDate) {
346 this.id = id;
347 this.startDate = startDate;
348 this.endDate = endDate;
349 tags = new ArrayList<Tag>();
350 }
351
352 public AssetId getId() {
353 return id;
354 }
355
356 public Date getStartDate() {
357 return startDate;
358 }
359
360 public Date getEndDate() {
361 return endDate;
362 }
363
364 public Collection<Tag> getTags() {
365 return tags;
366 }
367
368 private void addTag(Tag tag) {
369 tags.add(tag);
370 }
371
372 public String toString() {
373 return id.toString() + "|startdate:" + startDate + "|enddate:" + endDate + "|tags:" + tags;
374 }
375 }
376 }