View Javadoc

1   /*
2    * Copyright 2010 FatWire Corporation. All Rights Reserved.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.fatwire.gst.foundation.url.db;
17  
18  import java.util.Arrays;
19  import java.util.Collection;
20  import java.util.Date;
21  import java.util.HashSet;
22  import java.util.Set;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.commons.logging.Log;
26  
27  import COM.FutureTense.Interfaces.ICS;
28  import COM.FutureTense.Util.ftErrors;
29  
30  import com.fatwire.assetapi.data.AssetId;
31  import com.fatwire.gst.foundation.CSRuntimeException;
32  import com.fatwire.gst.foundation.controller.AssetIdWithSite;
33  import com.fatwire.gst.foundation.facade.logging.LogUtil;
34  import com.fatwire.gst.foundation.facade.runtag.asset.FilterAssetsByDate;
35  import com.fatwire.gst.foundation.facade.sql.Row;
36  import com.fatwire.gst.foundation.facade.sql.SqlHelper;
37  import com.fatwire.gst.foundation.url.WraPathTranslationService;
38  import com.fatwire.gst.foundation.vwebroot.VirtualWebroot;
39  import com.fatwire.gst.foundation.vwebroot.VirtualWebrootApiBypassDao;
40  import com.fatwire.gst.foundation.vwebroot.VirtualWebrootDao;
41  import com.fatwire.gst.foundation.wra.SimpleWRADao;
42  import com.fatwire.gst.foundation.wra.SimpleWra;
43  import com.openmarket.xcelerate.asset.AssetIdImpl;
44  
45  /**
46   * WraPathTranslationService that is backed by the GSTUrlRegistry table.
47   * 
48   * @author Dolf Dijkstra
49   * @since Jun 17, 2010
50   */
51  
52  public class UrlRegistry2 implements WraPathTranslationService {
53      private static final Log LOG = LogUtil.getLog(UrlRegistry2.class);
54  
55      private final ICS ics;
56      private final SimpleWRADao wraDao;
57      private final VirtualWebrootDao vwDao;
58      private final UrlRegistryDao regDao;
59  
60      public UrlRegistry2(final ICS ics, final SimpleWRADao wraDao, final VirtualWebrootDao vwDao,
61              final UrlRegistryDao regDao) {
62          this.ics = ics;
63          this.wraDao = wraDao;
64          this.vwDao = vwDao;
65          this.regDao = regDao;
66      }
67  
68      @Override
69      public AssetIdWithSite resolveAsset(final String virtual_webroot, final String url_path) {
70          for (final VanityUrl asset : regDao.resolveAsset(virtual_webroot, url_path)) {
71              final String assettype = asset.getAssettype();
72              final long assetid = asset.getAssetid();
73              final AssetIdWithSite id = new AssetIdWithSite(assettype, assetid, asset.getOpt_site());
74              if (FilterAssetsByDate.isValidOnDate(ics, id, null)) {
75                  if (LOG.isDebugEnabled()) {
76                      LOG.debug("Resolved and validated effective date for asset " + id + " from virtual-webroot:"
77                              + virtual_webroot + " and url-path:" + url_path);
78                  }
79                  return id;
80              } else {
81                  if (LOG.isDebugEnabled()) {
82                      LOG.debug("Resolved asset "
83                              + id
84                              + " but it is not valid on the effective date as determined by the asset.filterassetsbydate tag.");
85                  }
86              }
87          }
88  
89          return null;
90      }
91  
92      @Override
93      public void addAsset(final AssetId id) {
94          if (LOG.isTraceEnabled()) {
95              LOG.trace("addAsset(AssetId) called for asset " + id);
96          }
97          updateAsset_(id);
98      }
99  
100     @Override
101     public void updateAsset(final AssetId id) {
102         if (LOG.isTraceEnabled()) {
103             LOG.trace("updateAsset(AssetId) called for asset " + id);
104         }
105 
106         updateAsset_(id);
107     }
108 
109     @Override
110     public void deleteAsset(final AssetId id) {
111         if (LOG.isTraceEnabled()) {
112             LOG.trace("deleteAsset(AssetId) called for asset " + id);
113         }
114         regDao.delete(id);
115     }
116 
117     private void addAsset_(final SimpleWra wra) {
118         final AssetId asset = wra.getId();
119 
120         final VirtualWebroot vw = vwDao.lookupVirtualWebrootForUri(wra.getPath());
121 
122         if (vw != null) {
123             final String site = wraDao.resolveSite(asset);
124             regDao.add(wra, vw, site);
125 
126         } else {
127             if (LOG.isTraceEnabled()) {
128                 LOG.trace("Did not add WRA " + asset + " to url registry because no valid virtual webroot was found");
129             }
130         }
131 
132     }
133 
134     private boolean compare(final Date d1, final Date d2) {
135         if (d1 == null && d2 == null) {
136             return true;
137         }
138 
139         if (d1 == null && d2 != null) {
140             return false;
141         }
142         return d1.equals(d2);
143 
144     }
145 
146     private boolean compare(final VanityUrl url, final SimpleWra wra) {
147         // path, startdate && enddate all the same?
148         if (url == null) {
149             return false;
150         }
151         if (wra == null) {
152             return false;
153             // path cannot be null
154         }
155 
156         if (wra.getPath().equals(url.getPath()) == false) {
157             return false;
158         }
159 
160         if (compare(wra.getEndDate(), url.getEnddate()) == false) {
161             return false;
162         }
163         if (compare(wra.getStartDate(), url.getStartdate()) == false) {
164             return false;
165         }
166 
167         return true;
168     }
169 
170     public void updateAsset_(final AssetId id) {
171         /*
172          * here is the optimization question, what is faster, the select on the
173          * urlregtable or on the assettable? Probably it depends on number rows
174          * in table. If urlregtable is smaller than individual assettype table
175          * the lookup for registry table first is probably preferred. Otherwise,
176          * change to logic below to first lookup the wraDao.getWra().
177          */
178         final SimpleWra wra = wraDao.getWra(id);
179         if (isWra(wra)) {
180             final VanityUrl row = regDao.read(id);
181             if (!compare(row, wra)) {
182                 regDao.delete(id);
183                 addAsset_(wra);
184             } else if (row == null) {
185                 addAsset_(wra);
186             }
187         } else {
188             regDao.delete(id);
189         }
190 
191     }
192 
193     private boolean isWra(final SimpleWra wra) {
194         return wra != null && StringUtils.isNotBlank(wra.getPath()) && StringUtils.isNotBlank(wra.getTemplate());
195     }
196 
197     /**
198      * Rebuild all entries in the GST URL Registry table. Uses brute force
199      * method and can take a very long time.
200      * 
201      * @param stream stream a message back to the browser to prevent timeouts
202      */
203     public void rebuild(boolean stream) {
204         if (!ics.UserIsMember("xceladmin")) {
205             throw new CSRuntimeException("xceladmin user required to rebuild URL Registry", ftErrors.noprivs);
206         }
207         regDao.clear();
208         if (stream)
209             ics.StreamText("Re-creating url registry entries for ");
210         for (String type : _lookupWraAssetTypes()) {
211             LOG.debug("Re-creating all registry entries for asset type " + type);
212             if (stream)
213                 ics.StreamText("Asset type: " + type);
214             for (Row r : SqlHelper.select(ics, type, "SELECT id,template,path,startdate,enddate FROM " + type
215                     + " WHERE status!='VO' AND path IS NOT NULL and template IS NOT NULL")) {
216                 long id = r.getLong("id");
217                 AssetId aid = new AssetIdImpl(type, id);
218                 SimpleWra wra = new SimpleWra(r, aid);
219                 if (isWra(wra)) {
220                     LOG.debug("Attempting to rebuild registry entry for " + aid);
221                     // stream to prevent timeouts...???? :-(
222                     if (stream)
223                         ics.StreamText(" " + id); // stream immediately (don't
224                                                   // use StreamEvalBytes)
225                     addAsset_(wra);
226                 }
227             }
228         }
229         if (stream)
230             ics.StreamText("...completed");
231         LOG.debug("Rebuild completed");
232     }
233 
234     private final Collection<String> SYSTEM_TYPES = Arrays.asList("Template", "CSElement", "SiteEntry", "Collection",
235             "Page", "Query", "Link", "Dimension", "DimensionSet", "AttrTypes", "AdvCols", "Segments", "Promotions",
236             "ScalarVals", "HistoryVals", "HFields", "GSTFilter", "GSTAttribute", "GSTPDefinition", "GSTDefinition",
237             "GSTVirtualWebroot", "GSTProperty", "FW_View", "FW_Application");
238 
239     private Collection<String> _lookupWraAssetTypes() {
240         Set<String> x = new HashSet<String>();
241         for (Row r : SqlHelper.select(ics, "AssetType", "select assettype from AssetType")) {
242             String type = r.getString("assettype");
243             if (!SYSTEM_TYPES.contains(type)) {
244                 x.add(type); // TODO: be much smarter. Exclude flex definitions,
245                              // parent devs, filters. Get fancy and exclude
246                              // non-compliant definitions.
247             }
248             
249         }
250         x.add("Page"); // yes, I know it's listed as a system asset type, but it's both system and WRA in 11g.
251         return x;
252     }
253 
254     @Deprecated
255     public static UrlRegistry2 lookup(final ICS ics) {
256         final Object o = ics.GetObj(UrlRegistry2.class.getName());
257         if (o instanceof UrlRegistry2) {
258             return (UrlRegistry2) o;
259         }
260 
261         final UrlRegistry2 x = new UrlRegistry2(ics, new DbSimpleWRADao(ics), new VirtualWebrootApiBypassDao(ics),
262                 new UrlRegistryDaoImpl(ics));
263 
264         ics.SetObj(UrlRegistry2.class.getName(), x);
265         return x;
266     }
267 
268    
269 
270 }