001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.odf.oai; 017 018import java.io.IOException; 019import java.text.ParseException; 020import java.text.SimpleDateFormat; 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Collection; 024import java.util.Date; 025import java.util.TimeZone; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.cocoon.ProcessingException; 031import org.apache.cocoon.environment.ObjectModelHelper; 032import org.apache.cocoon.environment.Request; 033import org.apache.cocoon.xml.XMLUtils; 034import org.apache.commons.lang.StringUtils; 035import org.xml.sax.SAXException; 036 037import org.ametys.cms.repository.DefaultContent; 038import org.ametys.odf.ODFHelper; 039import org.ametys.odf.catalog.CatalogsManager; 040import org.ametys.odf.program.Program; 041import org.ametys.odf.program.ProgramFactory; 042import org.ametys.plugins.repository.AmetysObjectIterable; 043import org.ametys.plugins.repository.UnknownAmetysObjectException; 044import org.ametys.plugins.repository.query.SortCriteria; 045import org.ametys.plugins.repository.query.expression.AndExpression; 046import org.ametys.plugins.repository.query.expression.DateExpression; 047import org.ametys.plugins.repository.query.expression.Expression; 048import org.ametys.plugins.repository.query.expression.Expression.Operator; 049 050/** 051 * Generator for the <code>ListIdentifiers</code> verb. 052 */ 053public class ListIdentifiersGenerator extends AbstractOAIVerbGenerator implements Serviceable 054{ 055 /** The OAI-PMH Sets Extension Point*/ 056 private OaiSetExtensionPoint _oaiSetEP; 057 058 private CatalogsManager _catalogsManager; 059 060 private ODFHelper _odfHelper; 061 062 @Override 063 public void service(ServiceManager serviceManager) throws ServiceException 064 { 065 _oaiSetEP = (OaiSetExtensionPoint) serviceManager.lookup(OaiSetExtensionPoint.ROLE); 066 _catalogsManager = (CatalogsManager) serviceManager.lookup(CatalogsManager.ROLE); 067 _odfHelper = (ODFHelper) serviceManager.lookup(ODFHelper.ROLE); 068 } 069 070 @Override 071 protected Collection<String> getRequiredParameters() 072 { 073 return Arrays.asList("verb", "metadataPrefix"); 074 } 075 076 @Override 077 protected Collection<String> getAllowedParameters() 078 { 079 return Arrays.asList("verb", "from", "until", "metadataPrefix", "resumptionToken", "set"); 080 } 081 082 @Override 083 protected void generateVerb() throws IOException, SAXException, ProcessingException 084 { 085 Request request = ObjectModelHelper.getRequest(objectModel); 086 087 String token = request.getParameter("resumptionToken"); 088 089 if (StringUtils.isNotEmpty(token)) 090 { 091 generateError("badResumptionToken ", "This repository does not support resumption tokens"); 092 return; 093 } 094 095 String metadataPrefix = request.getParameter("metadataPrefix"); 096 097 if (!metadataPrefix.equals("cdm") && !metadataPrefix.equals("oai_dc")) 098 { 099 generateError("cannotDisseminateFormat", "The value of the metadataPrefix argument is not supported by the repository."); 100 return; 101 } 102 103 SimpleDateFormat fullFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 104 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 105 TimeZone tz = TimeZone.getTimeZone("UTC"); 106 fullFormat.setTimeZone(tz); 107 format.setTimeZone(tz); 108 109 ArrayList<Expression> expressions = new ArrayList<>(); 110 111 try 112 { 113 String fromParam = request.getParameter("from"); 114 115 if (fromParam != null) 116 { 117 Date from; 118 if (fromParam.indexOf('T') == -1) 119 { 120 from = format.parse(fromParam); 121 } 122 else 123 { 124 from = fullFormat.parse(fromParam); 125 } 126 127 expressions.add(new DateExpression("lastModified", Operator.GE, from)); 128 } 129 130 String untilParam = request.getParameter("until"); 131 132 if (untilParam != null) 133 { 134 Date until; 135 if (untilParam.indexOf('T') == -1) 136 { 137 until = format.parse(untilParam); 138 } 139 else 140 { 141 until = fullFormat.parse(untilParam); 142 } 143 144 expressions.add(new DateExpression("lastModified", Operator.LE, until)); 145 } 146 } 147 catch (ParseException ex) 148 { 149 generateError("badArgument", "One or more aguments are malformed."); 150 return; 151 } 152 153 OaiSet oaiSet = null; 154 String set = request.getParameter("set"); 155 156 if (StringUtils.isNotEmpty(set)) 157 { 158 oaiSet = _oaiSetEP.getExtension(set); 159 if (oaiSet == null) 160 { 161 generateError("noRecordsMatch", "The set specified as an argument does not exists."); 162 return; 163 } 164 } 165 166 Expression expression = new AndExpression(expressions.toArray(new Expression[]{})); 167 168 SortCriteria sortCriteria = new SortCriteria(); 169 sortCriteria.addCriterion(DefaultContent.METADATA_TITLE, true, true); 170 171 AmetysObjectIterable<Program> programs; 172 173 if (oaiSet != null) 174 { 175 programs = oaiSet.getRecords(expression, sortCriteria); 176 } 177 else 178 { 179 // FIXME Generate identifier for language "fr" and default catalog only. 180 programs = _odfHelper.getProgramItems(ProgramFactory.PROGRAM_CONTENT_TYPE, null, _catalogsManager.getDefaultCatalogName(), "fr", expression, sortCriteria); 181 } 182 183 XMLUtils.startElement(contentHandler, getTagName()); 184 185 for (Program program : programs) 186 { 187 try 188 { 189 String[] labels = program.getAllLabels(); 190 191 if (Arrays.asList(labels).contains("Live")) 192 { 193 program.switchToLabel("Live"); 194 saxProgram(program); 195 } 196 } 197 catch (UnknownAmetysObjectException e) 198 { 199 // no "Live" label, continue 200 } 201 } 202 203 XMLUtils.endElement(contentHandler, getTagName()); 204 } 205 206 /** 207 * Returns the surrounding tag name. 208 * @return the surrounding tag name. 209 */ 210 protected String getTagName() 211 { 212 return "ListIdentifiers"; 213 } 214 215 /** 216 * Generate the program information. 217 * @param program the program 218 * @throws SAXException if an error occurs 219 */ 220 protected void saxProgram(Program program) throws SAXException 221 { 222 XMLUtils.startElement(contentHandler, "header"); 223 224 XMLUtils.createElement(contentHandler, "identifier", program.getCDMId()); 225 226 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 227 TimeZone tz = TimeZone.getTimeZone("UTC"); 228 formatter.setTimeZone(tz); 229 230 Date date = program.getLastModified(); 231 232 XMLUtils.createElement(contentHandler, "datestamp", formatter.format(date)); 233 234 XMLUtils.endElement(contentHandler, "header"); 235 } 236}