001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.text.feed; 020 021import java.util.HashMap; 022import java.util.Map; 023 024import lucee.commons.lang.StringUtil; 025import lucee.runtime.type.Array; 026import lucee.runtime.type.Collection; 027import lucee.runtime.type.Collection.Key; 028import lucee.runtime.type.KeyImpl; 029import lucee.runtime.type.util.ListUtil; 030 031public class FeedDeclaration { 032 033 034 035 036 private static Map<String,FeedDeclaration> declarations = new HashMap<String,FeedDeclaration>(); 037 private static FeedDeclaration defaultDeclaration; 038 static { 039 040 041 042// RSS 2.0 043 Map<String,El> decl=new HashMap<String,El>(); 044 decl.put("rss", new El(El.QUANTITY_1,new Attr("version"))); 045 // rss.channel * 046 decl.put("rss.channel.item", new El(El.QUANTITY_0_N,true)); 047 decl.put("rss.channel.category", new El(El.QUANTITY_0_N,new Attr("domain"))); 048 decl.put("rss.channel.cloud", new El(El.QUANTITY_AUTO,new Attr[]{ 049 new Attr("domain"),new Attr("port"),new Attr("path"),new Attr("registerProcedure"),new Attr("protocol")})); 050 decl.put("rss.channel.image", new El(El.QUANTITY_AUTO)); 051 052 // rss.channel.item * 053 decl.put("rss.channel.item.author", new El(El.QUANTITY_0_1)); 054 decl.put("rss.channel.item.category", new El(El.QUANTITY_0_N,new Attr("domain"))); 055 decl.put("rss.channel.item.comments", new El(El.QUANTITY_0_1)); 056 decl.put("rss.channel.item.enclosure", new El(El.QUANTITY_0_N,new Attr[]{ 057 new Attr("url"),new Attr("length"),new Attr("type")})); 058 decl.put("rss.channel.item.guid", new El(El.QUANTITY_0_1,new Attr("isPermaLink","true"))); 059 decl.put("rss.channel.item.pubDate", new El(El.QUANTITY_0_1)); 060 decl.put("rss.channel.item.source", new El(El.QUANTITY_0_1,new Attr("url"))); 061 062 // rss.channel.item + 063 decl.put("rss.channel.item.title", new El(El.QUANTITY_1)); 064 decl.put("rss.channel.item.description", new El(El.QUANTITY_1,new Attr[]{}));// muss auch sein das er value anlegt 065 066 // rss.channel.item ? 067 decl.put("rss.channel.item.link", new El(El.QUANTITY_0_1));// muss auch sein das er value anlegt 068 069 // rss.channel.item 1 070 decl.put("rss.channel.image.url", new El(El.QUANTITY_1)); 071 decl.put("rss.channel.image.title", new El(El.QUANTITY_1)); 072 decl.put("rss.channel.image.link", new El(El.QUANTITY_1)); 073 074 // rss.channel.item * 075 decl.put("rss.channel.image.width", new El(El.QUANTITY_0_N)); 076 decl.put("rss.channel.image.height", new El(El.QUANTITY_0_N)); 077 decl.put("rss.channel.image.description", new El(El.QUANTITY_0_N)); 078 079 decl.put("rss.channel.textInput.title", new El(El.QUANTITY_1)); 080 decl.put("rss.channel.textInput.description", new El(El.QUANTITY_1)); 081 decl.put("rss.channel.textInput.name", new El(El.QUANTITY_1)); 082 decl.put("rss.channel.textInput.link", new El(El.QUANTITY_1)); 083 084 FeedDeclaration fd = new FeedDeclaration(decl,"rss.channel","rss_2.0"); 085 declarations.put("rss", fd); 086 declarations.put("rss_2.0", fd); 087 declarations.put("rss_2", fd); 088 089 090 // RSS 0.92 091 decl=new HashMap<String, El>(); 092 decl.put("rss", new El(El.QUANTITY_1,new Attr("version"))); 093 // rss.channel * 094 decl.put("rss.channel.item", new El(El.QUANTITY_0_N)); 095 decl.put("rss.channel.category", new El(El.QUANTITY_0_N,new Attr("domain"))); 096 decl.put("rss.channel.cloud", new El(El.QUANTITY_AUTO,new Attr[]{ 097 new Attr("domain"),new Attr("port"),new Attr("path"),new Attr("registerProcedure"),new Attr("protocol")})); 098 decl.put("rss.channel.image", new El(El.QUANTITY_AUTO)); 099 100 // rss.channel.item * 101 decl.put("rss.channel.item.author", new El(El.QUANTITY_0_1)); 102 decl.put("rss.channel.item.category", new El(El.QUANTITY_0_N,new Attr("domain","leer"))); 103 decl.put("rss.channel.item.comments", new El(El.QUANTITY_0_1)); 104 decl.put("rss.channel.item.enclosure", new El(El.QUANTITY_0_N,new Attr[]{ 105 new Attr("url"),new Attr("length"),new Attr("type")})); 106 decl.put("rss.channel.item.guid", new El(El.QUANTITY_0_1,new Attr("isPermaLink","true"))); 107 decl.put("rss.channel.item.pubDate", new El(El.QUANTITY_0_1)); 108 decl.put("rss.channel.item.source", new El(El.QUANTITY_0_1,new Attr("url"))); 109 110 // rss.channel.item + 111 decl.put("rss.channel.item.title", new El(El.QUANTITY_1)); 112 113 // rss.channel.item ? 114 decl.put("rss.channel.item.link", new El(El.QUANTITY_0_1));// muss auch sein das er value anlegt 115 116 // rss.channel.item 1 117 decl.put("rss.channel.image.url", new El(El.QUANTITY_1)); 118 decl.put("rss.channel.image.title", new El(El.QUANTITY_1)); 119 decl.put("rss.channel.image.link", new El(El.QUANTITY_1)); 120 121 // rss.channel.item * 122 decl.put("rss.channel.image.width", new El(El.QUANTITY_0_N)); 123 decl.put("rss.channel.image.height", new El(El.QUANTITY_0_N)); 124 decl.put("rss.channel.image.description", new El(El.QUANTITY_0_N)); 125 126 decl.put("rss.channel.textInput.title", new El(El.QUANTITY_1)); 127 decl.put("rss.channel.textInput.description", new El(El.QUANTITY_1)); 128 decl.put("rss.channel.textInput.name", new El(El.QUANTITY_1)); 129 decl.put("rss.channel.textInput.link", new El(El.QUANTITY_1)); 130 131 fd = new FeedDeclaration(decl,"rss.channel","rss_0.92"); 132 declarations.put("rss_0.92", fd); 133 134 135 // RSS 0.91 136 decl=new HashMap<String, El>(); 137 decl.put("rss", new El(El.QUANTITY_1,new Attr("version"))); 138 // rss.channel * 139 decl.put("rss.channel.item", new El(El.QUANTITY_0_N)); 140 decl.put("rss.channel.category", new El(El.QUANTITY_0_N,new Attr("domain"))); 141 decl.put("rss.channel.cloud", new El(El.QUANTITY_AUTO,new Attr[]{ 142 new Attr("domain"),new Attr("port"),new Attr("path"),new Attr("registerProcedure"),new Attr("protocol")})); 143 decl.put("rss.channel.image", new El(El.QUANTITY_AUTO)); 144 145 // rss.channel.item * 146 decl.put("rss.channel.item.author", new El(El.QUANTITY_0_1)); 147 decl.put("rss.channel.item.category", new El(El.QUANTITY_0_N,new Attr("domain","leer"))); 148 decl.put("rss.channel.item.comments", new El(El.QUANTITY_0_1)); 149 decl.put("rss.channel.item.enclosure", new El(El.QUANTITY_0_N,new Attr[]{ 150 new Attr("url"),new Attr("length"),new Attr("type")})); 151 decl.put("rss.channel.item.guid", new El(El.QUANTITY_0_1,new Attr("isPermaLink","true"))); 152 decl.put("rss.channel.item.pubDate", new El(El.QUANTITY_0_1)); 153 decl.put("rss.channel.item.source", new El(El.QUANTITY_0_1,new Attr("url"))); 154 155 // rss.channel.item 1 156 decl.put("rss.channel.image.url", new El(El.QUANTITY_1)); 157 decl.put("rss.channel.image.title", new El(El.QUANTITY_1)); 158 decl.put("rss.channel.image.link", new El(El.QUANTITY_1)); 159 160 // rss.channel.item * 161 decl.put("rss.channel.image.width", new El(El.QUANTITY_0_N)); 162 decl.put("rss.channel.image.height", new El(El.QUANTITY_0_N)); 163 decl.put("rss.channel.image.description", new El(El.QUANTITY_0_N)); 164 165 decl.put("rss.channel.textInput.title", new El(El.QUANTITY_1)); 166 decl.put("rss.channel.textInput.description", new El(El.QUANTITY_1)); 167 decl.put("rss.channel.textInput.name", new El(El.QUANTITY_1)); 168 decl.put("rss.channel.textInput.link", new El(El.QUANTITY_1)); 169 170 fd = new FeedDeclaration(decl,"rss.channel","rss_0.91"); 171 declarations.put("rss_0.91", fd); 172 173 174 175 // ATOM 176 decl=new HashMap<String, El>(); 177 decl.put("feed", new El(El.QUANTITY_1,new Attr("version"))); 178 179 decl.put("feed.author.name", new El(El.QUANTITY_1)); 180 decl.put("feed.title", new El(El.QUANTITY_1, new Attr[]{})); 181 decl.put("feed.link", new El(El.QUANTITY_0_N)); 182 decl.put("feed.entry", new El(El.QUANTITY_0_N)); 183 decl.put("feed.entry.author", new El(El.QUANTITY_0_N)); 184 decl.put("feed.entry.contributor", new El(El.QUANTITY_0_N)); 185 decl.put("feed.entry.content", new El(El.QUANTITY_0_N)); 186 decl.put("feed.entry.link", new El(El.QUANTITY_0_N)); 187 decl.put("feed.entry.title", new El(El.QUANTITY_1,new Attr[]{})); 188 decl.put("feed.entry.summary", new El(El.QUANTITY_1,new Attr[]{new Attr("type","text/plain"),new Attr("mode","xml")})); 189 190 fd = new FeedDeclaration(decl,"feed","atom"); 191 declarations.put("atom", fd); 192 193 194 195 defaultDeclaration=new FeedDeclaration(new HashMap<String, El>(),null,"custom"); 196 } 197 198 199 private Map<String, El> declaration; 200 private Key[] entryLevel; 201 private String type; 202 203 private FeedDeclaration(Map<String,El> declaration, String entryLevel,String type) { 204 this.declaration=declaration; 205 206 if(!StringUtil.isEmpty(entryLevel)) { 207 Array array = ListUtil.listToArray(entryLevel, '.'); 208 this.entryLevel=new Collection.Key[array.size()]; 209 for(int i=0;i<this.entryLevel.length;i++) { 210 this.entryLevel[i]=KeyImpl.toKey(array.get(i+1,null),null); 211 } 212 } 213 else this.entryLevel=new Collection.Key[0]; 214 this.type=type; 215 } 216 217 218 public static FeedDeclaration getInstance(String decName) { 219 FeedDeclaration fd= declarations.get(decName); 220 if(fd!=null)return fd; 221 222 if(StringUtil.startsWithIgnoreCase(decName, "rss")) 223 fd=declarations.get("rss"); 224 if(fd!=null)return fd; 225 226 if(StringUtil.startsWithIgnoreCase(decName, "atom")) 227 fd=declarations.get("atom"); 228 if(fd!=null)return fd; 229 230 return defaultDeclaration; 231 } 232 233 234 class FeedDeclarationItem { 235 236 } 237 238 239 /** 240 * @return the declaration 241 */ 242 public Map<String, El> getDeclaration() { 243 return declaration; 244 } 245 246 247 /** 248 * @return the entryLevel 249 */ 250 public Key[] getEntryLevel() { 251 return entryLevel; 252 } 253 254 255 public String getType() { 256 return type; 257 } 258}