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; 020 021import org.apache.commons.lang3.StringUtils; 022 023import org.ametys.odf.program.AbstractProgram; 024import org.ametys.odf.program.Program; 025import org.ametys.plugins.repository.AmetysObjectFactory; 026import org.ametys.plugins.repository.AmetysRepositoryException; 027import org.ametys.plugins.repository.UnknownAmetysObjectException; 028import org.ametys.web.repository.page.Page; 029 030import com.google.common.base.Splitter; 031 032/** 033 * {@link AmetysObjectFactory} handling {@link ProgramPage}. 034 */ 035public class ProgramPageFactory extends AbstractOdfPageFactory implements AmetysObjectFactory<ProgramPage> 036{ 037 @Override 038 public ProgramPage getAmetysObjectById(String id) throws AmetysRepositoryException 039 { 040 // Id is like program://_root?rootId=xxxx&programId=xxxx for Program 041 // Id is like program://path/to/subprogram?rootId=xxxx&programId=xxxx&parentId=xxxx for SubProgram 042 043 String path = StringUtils.substringBetween(id, "://", "?"); 044 String queryString = StringUtils.substringAfter(id, "?"); 045 Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString); 046 047 String rootId = ids.get("rootId"); 048 String programId = ids.get("programId"); 049 String parentId = ids.get("parentId"); 050 051 if ("_root".equals(path)) 052 { 053 // Case of a program 054 path = null; 055 } 056 057 Page root = _resolver.resolveById(rootId); 058 AbstractProgram program = _resolver.resolveById(programId); // program or subprogram 059 Program parent = StringUtils.isNotEmpty(parentId) ? _resolver.resolveById(parentId) : null; 060 Program parentProgramOrSelf = _getParentProgramOrSelf(parent, program); 061 062 // The identifier is invalid 063 if (parentProgramOrSelf == null) 064 { 065 throw new UnknownAmetysObjectException("The object '" + program.getId() + "' is not a Program and its given parent is null."); 066 } 067 068 // Test program restriction 069 if (!_odfPageHandler.isValidRestriction(root, _getParentProgramOrSelf(parent, program))) 070 { 071 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName()); 072 } 073 074 ProgramPage programPage = new ProgramPage(this, root, program, path, parent, null); 075 076 try 077 { 078 // Test if the virtual page really exists 079 programPage.getPathInSitemap(); 080 } 081 catch (UnknownAmetysObjectException e) 082 { 083 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName(), e); 084 } 085 086 return programPage; 087 } 088 089 private Program _getParentProgramOrSelf(Program parent, AbstractProgram self) throws UnknownAmetysObjectException 090 { 091 if (parent != null) 092 { 093 return parent; 094 } 095 096 // In old identifiers, a subprogram target doesn't need the parentId, so if we don't have a parent, it can be an old target with a subprogram 097 if (self instanceof Program) 098 { 099 return (Program) self; 100 } 101 102 return null; 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 // The identifier is invalid 134 if (parentProgramOrSelf == null) 135 { 136 return false; 137 } 138 139 if (!_odfPageHandler.isValidRestriction(root, parentProgramOrSelf)) 140 { 141 return false; 142 } 143 144 if (StringUtils.isNotBlank(_odfPageHandler.getLevel2Metadata(root))) 145 { 146 return _odfPageHandler.getProgramLevel1Value(root, parentProgramOrSelf) != null && _odfPageHandler.getProgramLevel2Value(root, parentProgramOrSelf) != null; 147 } 148 else if (StringUtils.isNotBlank(_odfPageHandler.getLevel1Metadata(root))) 149 { 150 return _odfPageHandler.getProgramLevel1Value(root, parentProgramOrSelf) != null; 151 } 152 153 return true; 154 } 155}