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.CmsConstants; 038import org.ametys.cms.repository.Content; 039import org.ametys.odf.ODFHelper; 040import org.ametys.odf.catalog.CatalogsManager; 041import org.ametys.odf.program.Program; 042import org.ametys.odf.program.ProgramFactory; 043import org.ametys.plugins.repository.AmetysObjectIterable; 044import org.ametys.plugins.repository.UnknownAmetysObjectException; 045import org.ametys.plugins.repository.query.SortCriteria; 046import org.ametys.plugins.repository.query.expression.AndExpression; 047import org.ametys.plugins.repository.query.expression.DateExpression; 048import org.ametys.plugins.repository.query.expression.Expression; 049import org.ametys.plugins.repository.query.expression.Expression.Operator; 050 051/** 052 * Generator for the <code>ListIdentifiers</code> verb. 053 */ 054public class ListIdentifiersGenerator extends AbstractOAIVerbGenerator implements Serviceable 055{ 056 /** The OAI-PMH Sets Extension Point*/ 057 private OaiSetExtensionPoint _oaiSetEP; 058 059 private CatalogsManager _catalogsManager; 060 061 private ODFHelper _odfHelper; 062 063 @Override 064 public void service(ServiceManager serviceManager) throws ServiceException 065 { 066 _oaiSetEP = (OaiSetExtensionPoint) serviceManager.lookup(OaiSetExtensionPoint.ROLE); 067 _catalogsManager = (CatalogsManager) serviceManager.lookup(CatalogsManager.ROLE); 068 _odfHelper = (ODFHelper) serviceManager.lookup(ODFHelper.ROLE); 069 } 070 071 @Override 072 protected Collection<String> getRequiredParameters() 073 { 074 return Arrays.asList("verb", "metadataPrefix"); 075 } 076 077 @Override 078 protected Collection<String> getAllowedParameters() 079 { 080 return Arrays.asList("verb", "from", "until", "metadataPrefix", "resumptionToken", "set"); 081 } 082 083 @Override 084 protected void generateVerb() throws IOException, SAXException, ProcessingException 085 { 086 Request request = ObjectModelHelper.getRequest(objectModel); 087 088 String token = request.getParameter("resumptionToken"); 089 090 if (StringUtils.isNotEmpty(token)) 091 { 092 generateError("badResumptionToken ", "This repository does not support resumption tokens"); 093 return; 094 } 095 096 String metadataPrefix = request.getParameter("metadataPrefix"); 097 098 if (!metadataPrefix.equals("cdm") && !metadataPrefix.equals("oai_dc")) 099 { 100 generateError("cannotDisseminateFormat", "The value of the metadataPrefix argument is not supported by the repository."); 101 return; 102 } 103 104 SimpleDateFormat fullFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 105 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 106 TimeZone tz = TimeZone.getTimeZone("UTC"); 107 fullFormat.setTimeZone(tz); 108 format.setTimeZone(tz); 109 110 ArrayList<Expression> expressions = new ArrayList<>(); 111 112 try 113 { 114 String fromParam = request.getParameter("from"); 115 116 if (fromParam != null) 117 { 118 Date from; 119 if (fromParam.indexOf('T') == -1) 120 { 121 from = format.parse(fromParam); 122 } 123 else 124 { 125 from = fullFormat.parse(fromParam); 126 } 127 128 expressions.add(new DateExpression("lastModified", Operator.GE, from)); 129 } 130 131 String untilParam = request.getParameter("until"); 132 133 if (untilParam != null) 134 { 135 Date until; 136 if (untilParam.indexOf('T') == -1) 137 { 138 until = format.parse(untilParam); 139 } 140 else 141 { 142 until = fullFormat.parse(untilParam); 143 } 144 145 expressions.add(new DateExpression("lastModified", Operator.LE, until)); 146 } 147 } 148 catch (ParseException ex) 149 { 150 generateError("badArgument", "One or more aguments are malformed."); 151 return; 152 } 153 154 OaiSet oaiSet = null; 155 String set = request.getParameter("set"); 156 157 if (StringUtils.isNotEmpty(set)) 158 { 159 oaiSet = _oaiSetEP.getExtension(set); 160 if (oaiSet == null) 161 { 162 generateError("noRecordsMatch", "The set specified as an argument does not exists."); 163 return; 164 } 165 } 166 167 Expression expression = new AndExpression(expressions.toArray(new Expression[]{})); 168 169 SortCriteria sortCriteria = new SortCriteria(); 170 sortCriteria.addCriterion(Content.ATTRIBUTE_TITLE, true, true); 171 172 try (AmetysObjectIterable<Program> programs = oaiSet != null 173 ? oaiSet.getRecords(expression, sortCriteria) 174 // FIXME Generate identifier for language "fr" and default catalog only 175 : _odfHelper.getProgramItems(ProgramFactory.PROGRAM_CONTENT_TYPE, null, _catalogsManager.getDefaultCatalogName(), "fr", expression, sortCriteria)) 176 { 177 178 XMLUtils.startElement(contentHandler, getTagName()); 179 180 for (Program program : programs) 181 { 182 try 183 { 184 String[] labels = program.getAllLabels(); 185 186 if (Arrays.asList(labels).contains(CmsConstants.LIVE_LABEL)) 187 { 188 program.switchToLabel(CmsConstants.LIVE_LABEL); 189 saxProgram(program); 190 } 191 } 192 catch (UnknownAmetysObjectException e) 193 { 194 // no "Live" label, continue 195 } 196 } 197 198 XMLUtils.endElement(contentHandler, getTagName()); 199 } 200 } 201 202 /** 203 * Returns the surrounding tag name. 204 * @return the surrounding tag name. 205 */ 206 protected String getTagName() 207 { 208 return "ListIdentifiers"; 209 } 210 211 /** 212 * Generate the program information. 213 * @param program the program 214 * @throws SAXException if an error occurs 215 */ 216 protected void saxProgram(Program program) throws SAXException 217 { 218 XMLUtils.startElement(contentHandler, "header"); 219 220 XMLUtils.createElement(contentHandler, "identifier", program.getCDMId()); 221 222 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 223 TimeZone tz = TimeZone.getTimeZone("UTC"); 224 formatter.setTimeZone(tz); 225 226 Date date = program.getLastModified(); 227 228 XMLUtils.createElement(contentHandler, "datestamp", formatter.format(date)); 229 230 XMLUtils.endElement(contentHandler, "header"); 231 } 232}