001/* 002 * Copyright 2010 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 */ 016 017package org.ametys.plugins.odfweb.repository; 018 019import java.util.Map; 020import java.util.Optional; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.avalon.framework.service.Serviceable; 025import org.apache.commons.lang3.StringUtils; 026 027import org.ametys.odf.program.AbstractProgram; 028import org.ametys.odf.program.Program; 029import org.ametys.plugins.repository.AmetysObjectFactory; 030import org.ametys.plugins.repository.AmetysObjectResolver; 031import org.ametys.plugins.repository.AmetysRepositoryException; 032import org.ametys.plugins.repository.UnknownAmetysObjectException; 033import org.ametys.web.repository.page.Page; 034 035import com.google.common.base.Splitter; 036 037/** 038 * {@link AmetysObjectFactory} handling {@link ProgramPage}. 039 */ 040public class ProgramPageFactory implements AmetysObjectFactory<ProgramPage>, Serviceable 041{ 042 /** Ametys object resolver */ 043 protected AmetysObjectResolver _resolver; 044 045 OdfPageHandler _odfPageHandler; 046 047 @Override 048 public void service(ServiceManager manager) throws ServiceException 049 { 050 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 051 _odfPageHandler = (OdfPageHandler) manager.lookup(OdfPageHandler.ROLE); 052 } 053 054 @Override 055 public ProgramPage getAmetysObjectById(String id) throws AmetysRepositoryException 056 { 057 // Id is like program://_root?rootId=xxxx&programId=xxxx for Program 058 // Id is like program://path/to/subprogram?rootId=xxxx&programId=xxxx&parentId=xxxx for SubProgram 059 060 String path = StringUtils.substringBetween(id, "://", "?"); 061 String queryString = StringUtils.substringAfter(id, "?"); 062 Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString); 063 064 String rootId = ids.get("rootId"); 065 String programId = ids.get("programId"); 066 String parentId = ids.get("parentId"); 067 068 if ("_root".equals(path)) 069 { 070 // Case of a program 071 path = null; 072 } 073 074 Page root = _resolver.resolveById(rootId); 075 AbstractProgram program = _resolver.resolveById(programId); // program or subprogram 076 Program parent = StringUtils.isNotEmpty(parentId) ? _resolver.resolveById(parentId) : null; 077 078 // Test program restriction 079 if (!_odfPageHandler.isValidRestriction(root, _getParentProgramOrSelf(parent, program))) 080 { 081 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName()); 082 } 083 084 ProgramPage programPage = new ProgramPage(_resolver, _odfPageHandler, root, program, path, parent, null); 085 086 try 087 { 088 // Test if the virtual page really exists 089 programPage.getPathInSitemap(); 090 } 091 catch (UnknownAmetysObjectException e) 092 { 093 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName(), e); 094 } 095 096 return programPage; 097 } 098 099 private Program _getParentProgramOrSelf(Program parent, AbstractProgram self) 100 { 101 return Optional.ofNullable(parent) 102 .orElseGet(() -> (Program) self); 103 } 104 105 @Override 106 public String getScheme() 107 { 108 return "program"; 109 } 110 111 @Override 112 public boolean hasAmetysObjectForId(String id) throws AmetysRepositoryException 113 { 114 int i = id.indexOf('?'); 115 116 String queryString = id.substring(i + 1); 117 Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString); 118 119 String rootId = ids.get("rootId"); 120 String programId = ids.get("programId"); 121 String parentId = ids.get("parentId"); 122 123 if (!_resolver.hasAmetysObjectForId(rootId) || !_resolver.hasAmetysObjectForId(programId)) 124 { 125 return false; 126 } 127 128 Page root = _resolver.resolveById(rootId); 129 AbstractProgram program = _resolver.resolveById(programId); // program or subprogram 130 Program parent = StringUtils.isNotEmpty(parentId) ? _resolver.resolveById(parentId) : null; 131 Program parentProgramOrSelf = _getParentProgramOrSelf(parent, program); 132 133 if (!_odfPageHandler.isValidRestriction(root, parentProgramOrSelf)) 134 { 135 return false; 136 } 137 138 return _odfPageHandler.getProgramLevel1Value(root, parentProgramOrSelf) != null && _odfPageHandler.getProgramLevel2Value(root, parentProgramOrSelf) != null; 139 } 140}