Author: wrzep Date: 2005-11-08 12:21:03 -0500 (Tue, 08 Nov 2005) New Revision: 1531 Added: branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/informa/ branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/informa/jars/ branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/informa/jars/informa.jar branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/jdom/ branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/jdom/jdom.jar branches/forge/interns/pawel/portal-extensions/forge-podcast/ branches/forge/interns/pawel/portal-extensions/forge-podcast/maven.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/project.properties branches/forge/interns/pawel/portal-extensions/forge-podcast/project.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/Podcast.java branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastDescriptor.java branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastNodeWatcher.java branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastPortlet.java branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastTools.java branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-app.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-portlet.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-service.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet-instances.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet.xml branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/forge.tld branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/portlet.tld branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/web.xml Modified: branches/forge/interns/pawel/portal-extensions/forge-ear/src/META-INF/application.xml branches/forge/interns/pawel/portal-extensions/portal-default/src/web/WEB-INF/default-portal.xml Log: Podcast portlet. Pawel Added: branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/informa/jars/informa.jar =================================================================== (Binary files differ) Property changes on: branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/informa/jars/informa.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/jdom/jdom.jar =================================================================== (Binary files differ) Property changes on: branches/forge/interns/pawel/portal-extensions/binaries/maven-repo-addons/jdom/jdom.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: branches/forge/interns/pawel/portal-extensions/forge-ear/src/META-INF/application.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-ear/src/META-INF/application.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-ear/src/META-INF/application.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -82,5 +82,10 @@ <web> <web-uri>forgeLogin.war</web-uri> </web> - </module> + </module> + <module> + <web> + <web-uri>forge-podcast.war</web-uri> + </web> + </module> </application> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/maven.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/maven.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/maven.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,24 @@ +<!-- + JBoss, the OpenSource J2EE webOS + Distributable under LGPL license. + See terms of license at gnu.org. + --> +<project xmlns:j="jelly:core" xmlns:ant="jelly:ant" xmlns:u="jelly:util"> + <!-- Default war-project goals --> + + <goal name="all"> + <attainGoal name="prj-all" /> + </goal> + + <goal name="build"> + <attainGoal name="prj-war-build" /> + </goal> + + <goal name="deploy"> + <attainGoal name="prj-war-deploy" /> + </goal> + + <goal name="clean"> + <attainGoal name="prj-clean" /> + </goal> +</project> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/project.properties =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/project.properties 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/project.properties 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,3 @@ +maven.repo.remote=http://repository.atlassian.com,http://www.ibiblio.org/maven,http://dist.codehaus.org/ +maven.junit.fork=yes +maven.war.src=${basedir}/src/web Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/project.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/project.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/project.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,63 @@ +<?xml version='1.0' encoding='ISO-8859-1'?> +<!-- + JBoss, the OpenSource J2EE webOS + Distributable under LGPL license. + See terms of license at gnu.org. + --> +<project> + <pomVersion>3</pomVersion> + <extend>../common.xml</extend> + <id>forge-podcast</id> + <name>Podcast portlet</name> + <currentVersion>1.0</currentVersion> + <organization> + <name>Pawel Wrzeszcz</name> + <url></url> + </organization> + <description></description> + + <dependencies> + <dependency> + <groupId>tmate</groupId> + <artifactId>javasvn</artifactId> + <version>1.0</version> + <jar>javasvn.jar</jar> + </dependency> + + <dependency> + <groupId>tmate</groupId> + <artifactId>jsch</artifactId> + <version>1.0</version> + <jar>jsch.jar</jar> + </dependency> + + <dependency> + <groupId>jboss-forge</groupId> + <artifactId>forge-common</artifactId> + <version>1.0</version> + </dependency> + + <dependency> + <groupId>aslibs</groupId> + <artifactId>javax.servlet</artifactId> + <version>1.0</version> + <jar>javax.servlet.jar</jar> + </dependency> + <dependency> + <groupId>informa</groupId> + <artifactId>informa</artifactId> + <version>0.6.5</version> + <jar>informa.jar</jar> + <properties> + <war.bundle>true</war.bundle> + </properties> + </dependency> + <dependency> + <id>jdom</id> + <version>1.0</version> + <properties> + <war.bundle>true</war.bundle> + </properties> + </dependency> + </dependencies> +</project> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/Podcast.java =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/Podcast.java 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/Podcast.java 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,278 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.forge.podcast; + +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.SimpleTimeZone; + +import java.util.Date; +import java.text.DateFormat; +import java.util.SimpleTimeZone; + +import java.net.URL; + +import org.jboss.forge.common.XmlTools; +import org.jboss.forge.common.projects.AbstractDescriptor; +import org.jboss.forge.common.projects.permissions.PermissionsChecker; +import org.jboss.forge.common.projects.permissions.RenderRequestPermissionsChecker; +import org.jboss.forge.common.projects.DomToXmlTransformer; + +import org.jboss.portal.common.context.DelegateContext; +import org.jboss.shotoku.ContentManager; + +import org.apache.xerces.parsers.DOMParser; +import org.xml.sax.InputSource; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.NamedNodeMap; + +import de.nava.informa.core.ChannelIF; +import de.nava.informa.impl.basic.ChannelBuilder; +import de.nava.informa.parsers.FeedParser; +import de.nava.informa.utils.ItemComparator; +import de.nava.informa.core.ItemIF; +import de.nava.informa.core.ItemEnclosureIF; +import de.nava.informa.core.ImageIF; + +/** + * A class holding the podcast feeds. + * + * @author Pawel Wrzeszcz + */ +public class Podcast extends AbstractDescriptor { + + /** + * <code>PODCAST_ELEMENT</code> - root tag in the xml file defining the list of watched feeds + */ + public static final String PODCAST_ELEMENT = "podcast"; + + /** + * <code>podcasts_number</code> - Defines maximum number of podcasts to display. + */ + public int podcastsNumber; + + private static int DEFAULT_PODCASTS_NUMBER = 50; + + /* Other tags in the xml file */ + private static final String FEED_ELEMENT = "feed"; + private static final String ID_ELEMENT = "id"; + private static final String URL_ELEMENT = "url"; + + private static final int BYTES_IN_MB = (1024*1024); + + private String portalName; + + /** + * <code>allItemsArr</code> - Array if ItemIF objects, containing items from all feeds. + */ + private Object[] allItemsArr; + + Podcast(String portalName, Node root) { + this.portalName = portalName; + + podcastsNumber = getPodcastsNumber(root); + + // Get the feeds nodes + HashSet<String> podcastNodes = new HashSet<String>(); + podcastNodes.add(FEED_ELEMENT); + + Set<Node> feedsNodes; + feedsNodes = getChildNodesSet(root, podcastNodes); + + // Parse each node to get the feed url + HashSet<String> propertiesTags = new HashSet<String>(); + propertiesTags.add(ID_ELEMENT); + propertiesTags.add(URL_ELEMENT); + + HashSet<Map<String,Node>> nodes = new HashSet<Map<String,Node>>(); + // Each Map in this Set describes one feed + // (contains it's id and url Nodes) + Map<String,Node> nodeProperties; + + for (Iterator iter = feedsNodes.iterator(); iter.hasNext();) { + Node n = (Node) iter.next(); + nodeProperties = getChildNodesMap(n, propertiesTags); + nodes.add(nodeProperties); + } + + // Parse and sort the items + allItemsArr = getAllItems(nodes).toArray(); + java.util.Arrays.sort((Object[]) allItemsArr, new ItemComparator(true)); + } + + /** + * Fills the given context with podcast information. + * + * @param context Context to fill. + */ + public void fillContext(DelegateContext context) { + + int iterations = Math.min(allItemsArr.length, podcastsNumber); + + for (int i = 0; i < iterations; i++) { + ItemIF item = (ItemIF) allItemsArr[i]; + DelegateContext nodeContext = new DelegateContext(); + + nodeContext.put("no", i+1); + nodeContext.put("title", item.getTitle()); + nodeContext.put("description", item.getDescription()); + + Date date = item.getDate(); + if (date != null) { + DateFormat dateFormat = DateFormat.getInstance(); + dateFormat.setTimeZone(new SimpleTimeZone(0, "GMT")); + String dateString = dateFormat.format(date) + " GMT"; + nodeContext.put("date", dateString); + } + + URL link = item.getLink(); + if (link != null) { + nodeContext.put("link", link.toString()); + } + + ItemEnclosureIF enclosure = item.getEnclosure(); + if (enclosure != null) { + DelegateContext enclosureContext = nodeContext.next("enclosure-link"); + + nodeContext.put("enclosure-type", enclosure.getType()); + nodeContext.put("enclosure-size", Math.round(enclosure.getLength() / BYTES_IN_MB)); + + URL enclosureLocation = enclosure.getLocation(); + if (enclosureLocation != null) { + nodeContext.put("enclosure-link", enclosureLocation.toString()); + } + } + + ChannelIF channel = item.getChannel(); + + nodeContext.put("channel-title", channel.getTitle()); + URL channelLocation = channel.getLocation(); + if (channelLocation != null) { + nodeContext.put("channel-link", channelLocation.toString()); + } + + ImageIF channelImage = channel.getImage(); + if ((channelImage != null) && (channelImage.getLocation() != null)) { + nodeContext.put("channel-image", channelImage.getLocation().toString()); + } + + context.append("podcast", nodeContext); + } + } + + + /** + * For the given Node, computes Set of it's child Nodes. + * Only child Nodes with names included in <code>nodesNames</code> Set + * appear in computed Set. + * + * @param root + * @param nodesNames + * @return Set containing <code>root</code>'s child Nodes, + * but only those with names included in <code>nodeNames</code> Set + */ + private Set getChildNodesSet(Node root, Set<String> nodesNames) { + HashSet ret = new HashSet<Node>(); + NodeList list = root.getChildNodes(); + + for (int i = 0; i < list.getLength(); i++) { + Node n = list.item(i); + if ((n.getNodeType() == Node.ELEMENT_NODE) + && (nodesNames.contains(n.getNodeName()))) { + ret.add(n); + } + } + + return ret; + } + + /** + * Similar to <code>getChildNodesSet(Node,Set)</code>. + * Map binds child Nodes names with appropriate Nodes. + */ + private Map getChildNodesMap(Node root, Set<String> nodesNames) { + HashMap ret = new HashMap<String,Node>(); + NodeList list = root.getChildNodes(); + + for (int i = 0; i < list.getLength(); i++) { + Node n = list.item(i); + if ((n.getNodeType() == Node.ELEMENT_NODE) + && (nodesNames.contains(n.getNodeName()))) { + ret.put(n.getNodeName(),n); + } + } + + return ret; + } + + /** + * For the given Set of feeds descripions, computes Set of all items from these feeds. + * + * @param nodes Set of Maps describing the feeds. + * For each feed, it's Map binds "id" and "url" with appropiate Nodes. + * + * @return Set of all items from feeds described in the given Set. + */ + private Set<ItemIF> getAllItems(Set<Map<String,Node>> nodes) { + HashSet<ItemIF> ret = new HashSet<ItemIF>(); + + for (Iterator iter = nodes.iterator(); iter.hasNext();) { + try { + Map nodeProperties = (Map<String,Node>) iter.next(); + + Node urlNode = (Node) nodeProperties.get(URL_ELEMENT); + URL url = new URL(XmlTools.unmarshallText(urlNode)); + + ChannelIF channel = FeedParser.parse(new ChannelBuilder(), url); + ret.addAll(channel.getItems()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + return ret; + } + + /** + * Parses attribute defining maximum number of podcasts to display. + * If it is not defined in the xml file, returns default value (DEFAULT_PODCASTS_NUMBER). + * + * @param root Root Node of the xml file. + * @return + */ + private int getPodcastsNumber(Node root) { + if (!root.hasAttributes()) { + return DEFAULT_PODCASTS_NUMBER; + } + NamedNodeMap m = root.getAttributes(); + String intString = XmlTools.unmarshallText(m.item(0)); + return Integer.parseInt(intString); + } + +} Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastDescriptor.java =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastDescriptor.java 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastDescriptor.java 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,90 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.forge.podcast; + +import java.io.IOException; +import java.util.Set; +import java.util.HashSet; + +import org.jboss.forge.podcast.PodcastTools; + +import org.apache.xerces.parsers.DOMParser; +import org.jboss.forge.common.ForgeHelper; +import org.jboss.forge.common.projects.ProjectsHelper; +import org.jboss.portal.common.context.DelegateContext; +import org.jboss.portlet.JBossRenderRequest; +import org.jboss.shotoku.ContentManager; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.jboss.logging.Logger; + +/** + * @author Pawel Wrzeszcz + * A class which handles xml parsing and accessing parsed feeds information. + */ +public class PodcastDescriptor { + + private static final Logger log = Logger.getLogger(PodcastDescriptor.class); + + private DelegateContext context; + + private Podcast podcast; + + private HashSet<String> feeds; + + public PodcastDescriptor(String portalName, ContentManager cm) { + try { + feeds = new HashSet<String>(); + + DOMParser parser = new DOMParser(); + parser.parse(new InputSource(cm.getNode(PodcastTools + .getXmlCmPath(portalName)).getContentInputStream())); + + Node root = parser.getDocument().getDocumentElement(); + + + if ((root.getNodeType() == Node.ELEMENT_NODE) + && (root.getNodeName().equals(Podcast.PODCAST_ELEMENT))) { + podcast = new Podcast(portalName, root); + } + + fillContext(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void fillContext() { + context = new DelegateContext(); + podcast.fillContext(context); + } + + public DelegateContext getContext(JBossRenderRequest request) { + + return context; + } +} Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastNodeWatcher.java =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastNodeWatcher.java 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastNodeWatcher.java 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,61 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.forge.podcast; + +import org.jboss.forge.common.service.NodeWatcher; +import org.jboss.forge.common.service.ResourceWatcher; + +import org.jboss.shotoku.ContentManager; + +/** +* @author Pawel Wrzeszcz +*/ + +public class PodcastNodeWatcher implements NodeWatcher { + private ResourceWatcher rw; + private ContentManager cm; + + public PodcastNodeWatcher(ContentManager cm) { + this.cm = cm; + } + + private PodcastDescriptor getDesc(String portalName) { + PodcastDescriptor desc = new PodcastDescriptor(portalName, cm); + + rw = new ResourceWatcher(cm); + rw.watchResource(PodcastTools.getXmlCmPath(portalName)); + + return desc; + } + + public Object init(String portalName) { + return getDesc(portalName); + } + + public Object nodeUpdate(String portalName, Object currentValue) { + if ((currentValue == null) || (rw.checkResources())) + return getDesc(portalName); + else + return null; + } +} Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastPortlet.java =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastPortlet.java 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastPortlet.java 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,67 @@ + /* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.jboss.forge.podcast; + +import java.io.IOException; + +import javax.portlet.PortletException; +import javax.portlet.PortletRequestDispatcher; + +import org.jboss.forge.common.ForgeHelper; +import org.jboss.forge.common.projects.Projects; +import org.jboss.forge.common.projects.ProjectsHelper; +import org.jboss.forge.common.projects.permissions.PermissionsChecker; +import org.jboss.forge.common.projects.permissions.RenderRequestPermissionsChecker; + +import org.jboss.portal.common.context.DelegateContext; +import org.jboss.portal.core.servlet.jsp.PortalJsp; + +import org.jboss.portlet.JBossPortlet; +import org.jboss.portlet.JBossRenderRequest; +import org.jboss.portlet.JBossRenderResponse; + +/** + * Podcast portlet. + * @author Pawel Wrzeszcz + */ +public class PodcastPortlet extends JBossPortlet { + + public void doView(JBossRenderRequest request, JBossRenderResponse response) + throws IOException, PortletException { + response.setContentType("text/html"); + + String portalName = ForgeHelper.getPortalName(request); + + // Getting the podcast context + DelegateContext context = PodcastTools.getDesc(portalName).getContext(request); + + // Displaying the JSP + request.setAttribute(PortalJsp.CTX_REQUEST, context); + + PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher( + ForgeHelper.createRepoAccessPath(portalName, PodcastTools + .getJspCmPath())); + rd.include(request, response); + + } +} Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastTools.java =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastTools.java 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/java/org/jboss/forge/podcast/PodcastTools.java 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,58 @@ +package org.jboss.forge.podcast; + +import org.jboss.forge.common.ForgeHelper; + +import org.jboss.shotoku.ContentManager; +import org.jboss.shotoku.aop.Inject; + +/** + * Common constants and functions. + * @author Pawel Wrzeszcz + */ +public class PodcastTools { + + /** + * <code>PODCAST_XML<code> - file defining the list of watched feeds + */ + private final static String PODCAST_XML = "podcast.xml"; + + /** + * <code>PODCAST_DIR</code> - directory in which file <code>PODCAST_XML<code> is stored. + */ + private final static String PODCAST_DIR = "podcast"; + + private final static String PODCAST_JSP = "podcast.jsp"; + private final static String PODCAST_JSP_DIR = "podcast"; + + @Inject + private static ContentManager cm; + + /** + * Path to the xml file defining list of watched feeds. + */ + public static String getXmlCmPath(String portalName) { + return portalName + "/" + PODCAST_DIR + "/" + PODCAST_XML; + } + + /** + * Path to the file displaying the podcast feeds. + */ + public static String getJspCmPath() { + return PODCAST_JSP_DIR + "/" + PODCAST_JSP; + } + + public static synchronized PodcastDescriptor getDesc(final String portalName) { + String cacheKey = PodcastDescriptor.class.getName(); + + PodcastDescriptor desc = (PodcastDescriptor) ForgeHelper + .getForgeManagement().getFromCache(portalName, cacheKey); + + if (desc == null) + desc = (PodcastDescriptor) ForgeHelper.getForgeManagement() + .addNodeWatcher(portalName, + cacheKey, + new PodcastNodeWatcher(cm)); + + return desc; + } +} Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-app.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-app.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-app.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,3 @@ +<jboss-app> + <app-name>podcast</app-name> +</jboss-app> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-portlet.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-portlet.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-portlet.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,6 @@ +<portlet-app> + <portlet> + <portlet-name>PodcastPortlet</portlet-name> + <security></security> + </portlet> +</portlet-app> \ No newline at end of file Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-service.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-service.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/jboss-service.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1 @@ +<server></server> \ No newline at end of file Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet-instances.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet-instances.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet-instances.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,7 @@ +<?xml version="1.0" standalone="yes"?> +<instances> + <instance> + <instance-name>PodcastPortletInstance</instance-name> + <component-ref>PodcastPortlet</component-ref> + </instance> +</instances> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/portlet.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" + version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> + <portlet> + <description>Podcast Portlet</description> + <portlet-name>PodcastPortlet</portlet-name> + <display-name>Feeds</display-name> + <portlet-class>org.jboss.forge.podcast.PodcastPortlet</portlet-class> + <supports> + <mime-type>text/html</mime-type> + <portlet-mode>VIEW</portlet-mode> + </supports> + <portlet-info> + <title>Podcast</title> + </portlet-info> + </portlet> + </portlet-app> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/forge.tld =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/forge.tld 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/forge.tld 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,139 @@ +<taglib xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" + version="2.0"> + <!-- + JBoss, the OpenSource J2EE webOS + Distributable under LGPL license. + See terms of license at gnu.org. + --> + <tlib-version>1.1</tlib-version> + <jsp-version>2.0</jsp-version> + <shortname>forge</shortname> + <info>Forge tags</info> + + <tag> + <name>pageURL</name> + <tagclass>org.jboss.forge.common.taglib.PageURLTag</tagclass> + <attribute> + <name>page</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>form</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>param</name> + <tagclass>org.jboss.forge.common.taglib.ParamTag</tagclass> + <attribute> + <name>name</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>value</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>wikiURL</name> + <tagclass>org.jboss.forge.common.taglib.WikiURLTag</tagclass> + <attribute> + <name>page</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>freezoneURL</name> + <tagclass>org.jboss.forge.common.taglib.FreezoneURLTag</tagclass> + <attribute> + <name>page</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>projectURL</name> + <tagclass>org.jboss.forge.common.taglib.ProjectURLTag</tagclass> + <attribute> + <name>project</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>page</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>form</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>categoryURL</name> + <tagclass>org.jboss.forge.common.taglib.CategoryURLTag</tagclass> + <attribute> + <name>category</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>form</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>selectedProject</name> + <tagclass>org.jboss.forge.common.taglib.SelectedProjectTag</tagclass> + </tag> + + <tag> + <name>imagePath</name> + <tagclass>org.jboss.forge.common.taglib.ImagePathTag</tagclass> + <attribute> + <name>src</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + <attribute> + <name>project</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>attrValue</name> + <tagclass>org.jboss.forge.common.taglib.AttrValueTag</tagclass> + <attribute> + <name>name</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>attrIf</name> + <tagclass>org.jboss.forge.common.taglib.AttrIfTag</tagclass> + <attribute> + <name>name</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> +</taglib> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/portlet.tld =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/portlet.tld 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/tld/portlet.tld 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,77 @@ +<taglib xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" + version="2.0"> + <tlib-version>1.1</tlib-version> + <jsp-version>2.0</jsp-version> + <shortname>JBoss Portal tags</shortname> + <info>JBoss Portal tags</info> + + <function> + <name>i18n</name> + <function-class>org.jboss.portal.core.servlet.jsp.taglib.PortalLib</function-class> + <function-signature>java.lang.String getMessage(java.lang.String)</function-signature> + </function> + + <function> + <name>out</name> + <function-class>org.jboss.portal.core.servlet.jsp.taglib.PortalLib</function-class> + <function-signature>java.lang.String out(java.lang.String)</function-signature> + </function> + + <function> + <name>i18nout</name> + <function-class>org.jboss.portal.core.servlet.jsp.taglib.PortalLib</function-class> + <function-signature>java.lang.String i18nOut(java.lang.String)</function-signature> + </function> + + <tag> + <name>if</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.IfTag</tagclass> + <attribute> + <name>ctx</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>iterate</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.IterateTag</tagclass> + <attribute> + <name>ctx</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>include</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.IncludeTag</tagclass> + <attribute> + <name>page</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>error</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.ErrorTag</tagclass> + <attribute> + <name>key</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + </tag> + + <tag> + <name>errors</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.ErrorsTag</tagclass> + </tag> + + <tag> + <name>success</name> + <tagclass>org.jboss.portal.core.servlet.jsp.taglib.SuccessTag</tagclass> + </tag> +</taglib> Added: branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/web.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/web.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/forge-podcast/src/web/WEB-INF/web.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!DOCTYPE web-app PUBLIC + "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> +<web-app> + <filter> + <filter-name>filesFromRepoFilter</filter-name> + <filter-class>org.jboss.forge.common.FilesFromRepoFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>filesFromRepoFilter</filter-name> + <url-pattern>/repo-access/*</url-pattern> + <dispatcher>INCLUDE</dispatcher> + </filter-mapping> +</web-app> \ No newline at end of file Modified: branches/forge/interns/pawel/portal-extensions/portal-default/src/web/WEB-INF/default-portal.xml =================================================================== --- branches/forge/interns/pawel/portal-extensions/portal-default/src/web/WEB-INF/default-portal.xml 2005-11-08 17:15:38 UTC (rev 1530) +++ branches/forge/interns/pawel/portal-extensions/portal-default/src/web/WEB-INF/default-portal.xml 2005-11-08 17:21:03 UTC (rev 1531) @@ -74,33 +74,33 @@ <height>2</height> <window-state>normal</window-state> </window> - </page> - - <!-- login page --> - <page> - <page-name>login</page-name> - <window> - <window-name>LoginWindow</window-name> - <instance-ref>forgeLogin.Login.LoginInstance</instance-ref> - <default>true</default> - <region>center</region> - <height>0</height> - </window> - <window> - <window-name>NavigationPortletWindowDefaultLogin</window-name> - <instance-ref>navigation.NavigationPortlet.NavigationPortletInstance</instance-ref> - <region>left</region> - <height>0</height> - <window-state>normal</window-state> - </window> - <window> - <window-name>AdsPortletWindowDefaultLogin</window-name> - <instance-ref>ads.AdsPortlet.AdsPortletInstance</instance-ref> - <region>left</region> - <height>2</height> - <window-state>normal</window-state> - </window> </page> + + <!-- login page --> + <page> + <page-name>login</page-name> + <window> + <window-name>LoginWindow</window-name> + <instance-ref>forgeLogin.Login.LoginInstance</instance-ref> + <default>true</default> + <region>center</region> + <height>0</height> + </window> + <window> + <window-name>NavigationPortletWindowDefaultLogin</window-name> + <instance-ref>navigation.NavigationPortlet.NavigationPortletInstance</instance-ref> + <region>left</region> + <height>0</height> + <window-state>normal</window-state> + </window> + <window> + <window-name>AdsPortletWindowDefaultLogin</window-name> + <instance-ref>ads.AdsPortlet.AdsPortletInstance</instance-ref> + <region>left</region> + <height>2</height> + <window-state>normal</window-state> + </window> + </page> <page> <page-name>softwaremap</page-name> @@ -383,7 +383,31 @@ <height>0</height> </window> - </page> - + </page> + + <page> + <page-name>podcast</page-name> + <window> + <window-name>NavigationPortletWindowDefaultPodcast</window-name> + <instance-ref>navigation.NavigationPortlet.NavigationPortletInstance</instance-ref> + <region>left</region> + <height>0</height> + <window-state>normal</window-state> + </window> + <window> + <window-name>AdsPortletWindowDefaultPodcast</window-name> + <instance-ref>ads.AdsPortlet.AdsPortletInstance</instance-ref> + <region>left</region> + <height>2</height> + <window-state>normal</window-state> + </window> + <window> + <window-name>PodcastPortletWindowDefaultPodcast</window-name> + <instance-ref>podcast.PodcastPortlet.PodcastPortletInstance</instance-ref> + <region>center</region> + <height>0</height> + </window> + </page> + </pages> </portal> |