/* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.riotfamily.linkcheck; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.Query; import org.hibernate.annotations.AccessType; import org.riotfamily.common.hibernate.ActiveRecord; import org.riotfamily.common.util.FormatUtils; import org.riotfamily.crawler.Href; import org.riotfamily.crawler.PageData; import org.slf4j.LoggerFactory; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @Entity @AccessType("field") @Table(name="riot_broken_links") public class BrokenLink extends ActiveRecord implements Serializable { // private Logger log = LoggerFactory.getLogger(Link.class); @Id private BrokenLinkPK primaryKey; private int statusCode; private String statusText; public BrokenLink() { } public BrokenLink(Href href) { this(href.getBaseUri(), href.getResolvedUri()); } public BrokenLink(String source, String destination) { if (primaryKey == null) { primaryKey = new BrokenLinkPK(); } primaryKey.setDestination(destination); primaryKey.setSource(source); } public BrokenLink(PageData pageData) { this(pageData.getReferrer(), pageData.getUrl()); this.statusCode = pageData.getStatusCode(); this.statusText = pageData.getError(); } public BrokenLinkPK getPrimaryKey() { return primaryKey; } public void setPrimaryKey(BrokenLinkPK primaryKey) { this.primaryKey = primaryKey; } public String getSource() { return primaryKey.getSource(); } public String getDestination() { return primaryKey.getDestination(); } public int getStatusCode() { return statusCode; } public void setStatusCode(int statusCode) { this.statusCode = statusCode; } public String getStatusText() { return statusText; } public void setStatusText(String statusText) { this.statusText = FormatUtils.truncate(statusText, 255); } @Override public int hashCode() { if (primaryKey != null) { return primaryKey.hashCode(); } return 1; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof BrokenLink) { BrokenLink other = (BrokenLink) obj; return ObjectUtils.nullSafeEquals(primaryKey, other.getPrimaryKey()); } return false; } @Override public String toString() { StringBuffer result = new StringBuffer(getDestination()); if (statusCode > 0) { result.append(" [").append(statusCode); if (StringUtils.hasText(statusText)) { result.append(" - ").append(statusText); } result.append(']'); } if (StringUtils.hasText(getSource())) { result.append(" (Source: ").append(getSource()).append(')'); } return result.toString(); } // ---------------------------------------------------------------------- // ActiveRecord methods // ---------------------------------------------------------------------- public static BrokenLink load(String source, String destination) { String hql = "from BrokenLink where source = :source and destination = :destination"; Query query = getSession().createQuery(hql); query.setParameter("source", source); query.setParameter("destination", destination); query.setMaxResults(1); return (BrokenLink) query.uniqueResult(); } public static void deleteAll() { String hql = "delete from BrokenLink"; Query query = getSession().createQuery(hql); query.executeUpdate(); } public static void saveAll(Collection<BrokenLink> links) { Iterator<BrokenLink> it = links.iterator(); while (it.hasNext()) { BrokenLink link = it.next(); if (link.getSource() == null) { LoggerFactory.getLogger(BrokenLink.class).error( "Trying to save broken link without a source. Possibly " + "this link refers to a broken crawler start page."); } else { getSession().saveOrUpdate(link); } } } @SuppressWarnings("unchecked") public static Collection<BrokenLink> findAllBrokenLinks() { String hql = "from BrokenLink order by id.source"; Query query = getSession().createQuery(hql); return query.list(); } public static int countBrokenLinks() { String hql = "select count(*) from BrokenLink"; Query query = getSession().createQuery(hql); Number count = (Number) query.uniqueResult(); return count.intValue(); } @SuppressWarnings("unchecked") public static Collection<String> findBrokenLinksOnPage(String url) { String hql = "select id.destination from BrokenLink where id.source = :url"; Query query = getSession().createQuery(hql); query.setParameter("url", url); return query.list(); } public static void deleteBrokenLinksFrom(String sourceUrl) { String hql = "delete from BrokenLink where id.source = :url"; Query query = getSession().createQuery(hql); query.setParameter("url", sourceUrl); query.executeUpdate(); } public static void deleteBrokenLinksTo(String destUrl) { String hql = "delete from BrokenLink where id.destination = :url"; Query query = getSession().createQuery(hql); query.setParameter("url", destUrl); query.executeUpdate(); } }