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}