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 /** 038 * Create a program page. 039 * @param root the ODF root page. 040 * @param program the program or subprogram. 041 * @param path The path from the virtual second level page. Can be null if abstract program is a {@link Program} 042 * @param parent the parent program in case of a subprogram, null otherwise 043 * @param parentPage the parent {@link Page} or null if not yet computed. 044 * @return The <code>ProgramPage</code> created 045 */ 046 public ProgramPage createProgramPage(Page root, AbstractProgram program, String path, Program parent, Page parentPage) 047 { 048 return new ProgramPage(root, getConfiguration(), this, program, path, parent, parentPage); 049 } 050 051 @Override 052 public ProgramPage getAmetysObjectById(String id) throws AmetysRepositoryException 053 { 054 // Id is like program://_root?rootId=xxxx&programId=xxxx for Program 055 // Id is like program://path/to/subprogram?rootId=xxxx&programId=xxxx&parentId=xxxx for SubProgram 056 057 String path = StringUtils.substringBetween(id, "://", "?"); 058 String queryString = StringUtils.substringAfter(id, "?"); 059 Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString); 060 061 String rootId = ids.get("rootId"); 062 String programId = ids.get("programId"); 063 String parentId = ids.get("parentId"); 064 065 if ("_root".equals(path)) 066 { 067 // Case of a program 068 path = null; 069 } 070 071 Page root = _resolver.resolveById(rootId); 072 AbstractProgram program = _resolver.resolveById(programId); // program or subprogram 073 Program parent = StringUtils.isNotEmpty(parentId) ? _resolver.resolveById(parentId) : null; 074 Program parentProgramOrSelf = _getParentProgramOrSelf(parent, program); 075 076 // The identifier is invalid 077 if (parentProgramOrSelf == null) 078 { 079 throw new UnknownAmetysObjectException("The object '" + program.getId() + "' is not a Program and its given parent is null."); 080 } 081 082 // Test program restriction 083 if (!_odfPageHandler.isValidRestriction(root, parentProgramOrSelf)) 084 { 085 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName()); 086 } 087 088 try 089 { 090 ProgramPage programPage = createProgramPage(root, program, path, parent, null); 091 092 // Test if the virtual page really exists 093 programPage.getPathInSitemap(); 094 095 return programPage; 096 } 097 catch (UnknownAmetysObjectException e) 098 { 099 throw new UnknownAmetysObjectException("There's no program child page " + programId + " for site " + root.getSiteName(), e); 100 } 101 } 102 103 private Program _getParentProgramOrSelf(Program parent, AbstractProgram self) throws UnknownAmetysObjectException 104 { 105 if (parent != null) 106 { 107 return parent; 108 } 109 110 // 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 111 if (self instanceof Program) 112 { 113 return (Program) self; 114 } 115 116 return null; 117 } 118 119 @Override 120 public String getScheme() 121 { 122 return "program"; 123 } 124 125 @Override 126 public boolean hasAmetysObjectForId(String id) throws AmetysRepositoryException 127 { 128 int i = id.indexOf('?'); 129 130 String queryString = id.substring(i + 1); 131 Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString); 132 133 String rootId = ids.get("rootId"); 134 String programId = ids.get("programId"); 135 String parentId = ids.get("parentId"); 136 137 if (!_resolver.hasAmetysObjectForId(rootId) || !_resolver.hasAmetysObjectForId(programId)) 138 { 139 return false; 140 } 141 142 Page root = _resolver.resolveById(rootId); 143 AbstractProgram program = _resolver.resolveById(programId); // program or subprogram 144 Program parent = StringUtils.isNotEmpty(parentId) ? _resolver.resolveById(parentId) : null; 145 Program parentProgramOrSelf = _getParentProgramOrSelf(parent, program); 146 147 // The identifier is invalid 148 if (parentProgramOrSelf == null) 149 { 150 return false; 151 } 152 153 if (!_odfPageHandler.isValidRestriction(root, parentProgramOrSelf)) 154 { 155 return false; 156 } 157 158 if (StringUtils.isNotBlank(_odfPageHandler.getLevel2Metadata(root))) 159 { 160 return _odfPageHandler.getProgramLevel1Value(root, parentProgramOrSelf) != null && _odfPageHandler.getProgramLevel2Value(root, parentProgramOrSelf) != null; 161 } 162 else if (StringUtils.isNotBlank(_odfPageHandler.getLevel1Metadata(root))) 163 { 164 return _odfPageHandler.getProgramLevel1Value(root, parentProgramOrSelf) != null; 165 } 166 167 return true; 168 } 169}