| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * 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. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| |
| package org.apache.roller.planet.business.jpa; |
| |
| import java.sql.Timestamp; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.List; |
| import jakarta.persistence.NoResultException; |
| import jakarta.persistence.Query; |
| import jakarta.persistence.TypedQuery; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.roller.RollerException; |
| |
| import org.apache.roller.planet.business.PlanetManager; |
| import org.apache.roller.planet.pojos.Planet; |
| import org.apache.roller.planet.pojos.SubscriptionEntry; |
| import org.apache.roller.planet.pojos.PlanetGroup; |
| import org.apache.roller.planet.pojos.Subscription; |
| import org.apache.roller.planet.business.AbstractManagerImpl; |
| import org.apache.roller.util.RollerConstants; |
| import org.apache.roller.weblogger.WebloggerException; |
| import org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy; |
| |
| /** |
| * Manages Planet Roller objects and entry aggregations in a database. |
| * |
| * @author Dave Johnson |
| */ |
| @com.google.inject.Singleton |
| public class JPAPlanetManagerImpl extends AbstractManagerImpl implements PlanetManager { |
| |
| private static final Log log = LogFactory.getLog(JPAPlanetManagerImpl.class); |
| |
| /** The strategy for this manager. */ |
| private final JPAPersistenceStrategy strategy; |
| |
| @com.google.inject.Inject |
| protected JPAPlanetManagerImpl(JPAPersistenceStrategy strategy) { |
| log.debug("Instantiating JPA Planet Manager"); |
| |
| this.strategy = strategy; |
| } |
| |
| |
| @Override |
| public void saveGroup(PlanetGroup group) throws RollerException { |
| strategy.store(group); |
| } |
| |
| @Override |
| public void saveEntry(SubscriptionEntry entry) throws RollerException { |
| strategy.store(entry); |
| } |
| |
| @Override |
| public void saveSubscription(Subscription sub) |
| throws RollerException { |
| Subscription existing = getSubscription(sub.getFeedURL()); |
| if (existing == null || (existing.getId().equals(sub.getId()))) { |
| strategy.store(sub); |
| } else { |
| throw new WebloggerException("ERROR: duplicate feed URLs not allowed"); |
| } |
| } |
| |
| @Override |
| public void deleteEntry(SubscriptionEntry entry) throws RollerException { |
| strategy.remove(entry); |
| } |
| |
| @Override |
| public void deleteGroup(PlanetGroup group) throws RollerException { |
| |
| group.getPlanet().getGroups().remove(group); |
| strategy.store(group.getPlanet()); |
| |
| strategy.remove(group); |
| } |
| |
| @Override |
| public void deleteSubscription(Subscription sub) |
| throws RollerException { |
| strategy.remove(sub); |
| } |
| |
| @Override |
| public Subscription getSubscription(String feedUrl) |
| throws RollerException { |
| TypedQuery<Subscription> q = strategy.getNamedQuery("Subscription.getByFeedURL", Subscription.class); |
| q.setParameter(1, feedUrl); |
| try { |
| return q.getSingleResult(); |
| } catch (NoResultException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public Subscription getSubscriptionById(String id) |
| throws RollerException { |
| return (Subscription) strategy.load( |
| Subscription.class, id); |
| } |
| |
| public Iterator<Subscription> getAllSubscriptions() { |
| try { |
| return (strategy.getNamedQuery( |
| "Subscription.getAll", Subscription.class).getResultList()).iterator(); |
| } catch (Exception e) { |
| throw new RuntimeException( |
| "ERROR fetching subscription collection", e); |
| } |
| } |
| |
| @Override |
| public int getSubscriptionCount() throws RollerException { |
| Query q = strategy.getNamedQuery("Subscription.getAll", Subscription.class); |
| return q.getResultList().size(); |
| } |
| |
| @Override |
| public List<Subscription> getTopSubscriptions(int offset, int length) |
| throws RollerException { |
| return getTopSubscriptions(null, offset, length); |
| } |
| |
| /** |
| * Get top X subscriptions, restricted by group. |
| */ |
| @Override |
| public List<Subscription> getTopSubscriptions( |
| PlanetGroup group, int offset, int len) throws RollerException { |
| List<Subscription> result; |
| if (group != null) { |
| TypedQuery<Subscription> q = strategy.getNamedQuery( |
| "Subscription.getByGroupOrderByInboundBlogsDesc", Subscription.class); |
| q.setParameter(1, group); |
| if (offset != 0) { |
| q.setFirstResult(offset); |
| } |
| if (len != -1) { |
| q.setMaxResults(len); |
| } |
| result = q.getResultList(); |
| } else { |
| TypedQuery<Subscription> q = strategy.getNamedQuery( |
| "Subscription.getAllOrderByInboundBlogsDesc", Subscription.class); |
| if (offset != 0) { |
| q.setFirstResult(offset); |
| } |
| if (len != -1) { |
| q.setMaxResults(len); |
| } |
| result = q.getResultList(); |
| } |
| return result; |
| } |
| |
| public PlanetGroup getGroup(String handle) throws RollerException { |
| TypedQuery<PlanetGroup> q = strategy.getNamedQuery("PlanetGroup.getByHandle", PlanetGroup.class); |
| q.setParameter(1, handle); |
| try { |
| return q.getSingleResult(); |
| } catch (NoResultException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public PlanetGroup getGroupById(String id) throws RollerException { |
| return (PlanetGroup) strategy.load(PlanetGroup.class, id); |
| } |
| |
| @Override |
| public void release() {} |
| |
| |
| @Override |
| public void savePlanet(Planet planet) throws RollerException { |
| strategy.store(planet); |
| } |
| |
| @Override |
| public Planet getWeblogger(String handle) throws RollerException { |
| TypedQuery<Planet> q = strategy.getNamedQuery("Planet.getByHandle", Planet.class); |
| q.setParameter(1, handle); |
| try { |
| return q.getSingleResult(); |
| } catch (NoResultException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public Planet getWebloggerById(String id) throws RollerException { |
| return (Planet)strategy.load(Planet.class, id); |
| } |
| |
| @Override |
| public List<Planet> getWebloggers() throws RollerException { |
| return strategy.getNamedQuery("Planet.getAll", Planet.class).getResultList(); |
| } |
| |
| public List<String> getGroupHandles(Planet planet) throws RollerException { |
| List<String> handles = new ArrayList<>(); |
| for (PlanetGroup group : getGroups(planet)) { |
| handles.add(group.getHandle()); |
| } |
| return handles; |
| } |
| |
| public List<PlanetGroup> getGroups(Planet planet) throws RollerException { |
| TypedQuery<PlanetGroup> q = strategy.getNamedQuery("PlanetGroup.getByPlanet", PlanetGroup.class); |
| q.setParameter(1, planet.getHandle()); |
| return q.getResultList(); |
| } |
| |
| @Override |
| public PlanetGroup getGroup(Planet planet, String handle) throws RollerException { |
| TypedQuery<PlanetGroup> q = strategy.getNamedQuery("PlanetGroup.getByPlanetAndHandle", PlanetGroup.class); |
| q.setParameter(1, planet.getHandle()); |
| q.setParameter(2, handle); |
| try { |
| return q.getSingleResult(); |
| } catch (NoResultException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public void deletePlanet(Planet planet) throws RollerException { |
| strategy.remove(planet); |
| } |
| |
| @Override |
| public void deleteEntries(Subscription sub) |
| throws RollerException { |
| for (Object entry : sub.getEntries()) { |
| strategy.remove(entry); |
| } |
| // make sure and clear the other side of the association |
| sub.getEntries().clear(); |
| } |
| |
| @Override |
| public List<Subscription> getSubscriptions() throws RollerException { |
| TypedQuery<Subscription> q = strategy.getNamedQuery("Subscription.getAllOrderByFeedURL", Subscription.class); |
| return q.getResultList(); |
| } |
| |
| @Override |
| public SubscriptionEntry getEntryById(String id) throws RollerException { |
| return (SubscriptionEntry) strategy.load(SubscriptionEntry.class, id); |
| } |
| |
| @Override |
| public List<SubscriptionEntry> getEntries(Subscription sub, int offset, int len) throws RollerException { |
| if (sub == null) { |
| throw new WebloggerException("subscription cannot be null"); |
| } |
| TypedQuery<SubscriptionEntry> q = strategy.getNamedQuery( |
| "SubscriptionEntry.getBySubscription", SubscriptionEntry.class); |
| q.setParameter(1, sub); |
| if (offset != 0) { |
| q.setFirstResult(offset); |
| } |
| if (len != -1) { |
| q.setMaxResults(len); |
| } |
| return q.getResultList(); |
| } |
| |
| @Override |
| public List<SubscriptionEntry> getEntries(PlanetGroup group, int offset, int len) throws RollerException { |
| return getEntries(group, null, null, offset, len); |
| } |
| |
| @Override |
| public List<SubscriptionEntry> getEntries( |
| PlanetGroup group, Date startDate, Date endDate, int offset, int len) throws RollerException { |
| |
| if (group == null) { |
| throw new WebloggerException("group cannot be null or empty"); |
| } |
| |
| List<SubscriptionEntry> ret; |
| try { |
| long startTime = System.currentTimeMillis(); |
| |
| StringBuilder sb = new StringBuilder(); |
| List<Object> params = new ArrayList<>(); |
| int size = 0; |
| sb.append("SELECT e FROM SubscriptionEntry e "); |
| sb.append("JOIN e.subscription.groups g "); |
| |
| params.add(size++, group.getHandle()); |
| sb.append("WHERE g.handle = ?").append(size); |
| |
| if (startDate != null) { |
| params.add(size++, new Timestamp(startDate.getTime())); |
| sb.append(" AND e.pubTime > ?").append(size); |
| } |
| if (endDate != null) { |
| params.add(size++, new Timestamp(endDate.getTime())); |
| sb.append(" AND e.pubTime < :?").append(size); |
| } |
| sb.append(" ORDER BY e.pubTime DESC"); |
| |
| TypedQuery<SubscriptionEntry> query = strategy.getDynamicQuery(sb.toString(), SubscriptionEntry.class); |
| for (int i=0; i<params.size(); i++) { |
| query.setParameter(i+1, params.get(i)); |
| } |
| if (offset > 0) { |
| query.setFirstResult(offset); |
| } |
| if (len != -1) { |
| query.setMaxResults(len); |
| } |
| |
| ret = query.getResultList(); |
| |
| long endTime = System.currentTimeMillis(); |
| |
| log.debug("Generated aggregation of " + ret.size() + " in " + |
| ((endTime-startTime) / RollerConstants.SEC_IN_MS) + " seconds"); |
| |
| } catch (Exception e) { |
| throw new WebloggerException(e); |
| } |
| |
| return ret; |
| } |
| |
| @Override |
| public void saveNewPlanetGroup(Planet planet, PlanetGroup planetGroup) throws WebloggerException { |
| |
| planetGroup.setPlanet( planet ); |
| strategy.store( planetGroup ); |
| |
| planet.getGroups().add( planetGroup ); |
| strategy.store( planet ); |
| } |
| } |
| |
| |
| |
| |
| |