/* * #! * Ontopoly Editor * #- * Copyright (C) 2001 - 2013 The Ontopia Project * #- * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * !# */ package ontopoly; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.ontopia.topicmaps.core.TopicMapIF; import net.ontopia.topicmaps.core.TopicMapStoreIF; import net.ontopia.topicmaps.entry.TopicMapReferenceIF; import net.ontopia.topicmaps.entry.TopicMapRepositoryIF; import net.ontopia.utils.ObjectUtils; import net.ontopia.utils.OntopiaRuntimeException; import ontopoly.model.TopicMap; import ontopoly.pages.ConvertPage; import ontopoly.pages.InternalErrorPageWithException; import ontopoly.pages.PageExpiredErrorPage; import ontopoly.pages.StartPage; import ontopoly.pages.UpgradePage; import org.apache.wicket.Page; import org.apache.wicket.PageParameters; import org.apache.wicket.Request; import org.apache.wicket.Response; import org.apache.wicket.RestartResponseException; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.protocol.http.PageExpiredException; import org.apache.wicket.protocol.http.WebRequest; import org.apache.wicket.protocol.http.WebRequestCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class OntopolyRequestCycle extends WebRequestCycle { private static final Logger log = LoggerFactory.getLogger(OntopolyRequestCycle.class); private static ThreadLocal<Map<String,TopicMap>> topicmaps = new ThreadLocal<Map<String,TopicMap>>(); public OntopolyRequestCycle(OntopolyApplication application, Request request, Response response) { super(application, (WebRequest)request, response); } @Override protected void onBeginRequest() { super.onBeginRequest(); } @Override protected void onEndRequest() { super.onEndRequest(); Map<String,TopicMap> tms = topicmaps.get(); if (tms != null && !tms.isEmpty()) { Iterator<TopicMap> iter = tms.values().iterator(); while (iter.hasNext()) { TopicMap topicmap = iter.next(); TopicMapIF tm = topicmap.getTopicMapIF(); TopicMapStoreIF store = tm.getStore(); try { store.commit(); } catch (Exception ex) { log.error("Problems occured while committing transaction", ex); } finally { store.close(); } } } if (tms != null) { tms.clear(); } } @Override protected void logRuntimeException(RuntimeException e) { // do not log unauthorized exceptions if (!(e instanceof org.apache.wicket.authorization.UnauthorizedInstantiationException)) super.logRuntimeException(e); } @SuppressWarnings("unchecked") @Override public Page onRuntimeException(Page page, RuntimeException e) { Map<String,TopicMap> tms = topicmaps.get(); if (tms != null && !tms.isEmpty()) { Iterator<TopicMap> iter = tms.values().iterator(); while (iter.hasNext()) { TopicMap topicmap = iter.next(); TopicMapIF tm = topicmap.getTopicMapIF(); TopicMapStoreIF store = tm.getStore(); try { store.abort(); } catch (Exception ex) { log.error("Problems occured while aborting transaction", ex); } finally { store.close(); } } } if (tms != null) { tms.clear(); } Throwable cause = e; if (cause instanceof WicketRuntimeException) cause = cause.getCause(); if (cause instanceof InvocationTargetException) cause = cause.getCause(); if (e instanceof PageExpiredException) { String referer = ((WebRequest)this.getRequest()).getHttpServletRequest().getHeader("Referer"); if (referer != null) { Pattern pattern = Pattern.compile("ontopoly.pages.\\w*"); Matcher matcher = pattern.matcher(referer); String pageName = ""; if (matcher.find()) pageName = matcher.group(); pattern = Pattern.compile("&([^&]*)=([^&]*)"); matcher = pattern.matcher(referer); Map<String,String> pageParametersMap = new HashMap<String,String>(); while (matcher.find()) pageParametersMap.put(matcher.group(1), matcher.group(2)); Class<? extends Page> classObjectForPage = null; try { classObjectForPage = (Class<? extends Page>)Class.forName(pageName); } catch(ClassNotFoundException cnfe) { //! System.out.println("Couldn't find a class with the name: "+pageName); } return new PageExpiredErrorPage(classObjectForPage, new PageParameters(pageParametersMap)); } } if (cause instanceof Exception) { return new InternalErrorPageWithException(page, e); } return super.onRuntimeException(page, e); } // --- public TopicMap getTopicMap(String topicMapId) { // go ahead and hand out topic map Map<String,TopicMap> tms = topicmaps.get(); TopicMap tm = (tms == null ? null : (TopicMap)tms.get(topicMapId)); if (tm == null) { if (tms == null) { tms = new HashMap<String,TopicMap>(); topicmaps.set(tms); } TopicMapRepositoryIF rep = OntopolyContext.getOntopolyRepository().getTopicMapRepository(); TopicMapStoreIF store = createStore(topicMapId, false, rep); tm = new TopicMap(store.getTopicMap(), topicMapId); tms.put(topicMapId, tm); } // check if topic map contains ontopoly ontology Class<? extends Page> pageClass = this.getResponsePageClass(); if (pageClass != null) { boolean performingUpgrade = ObjectUtils.equals(ConvertPage.class, pageClass); boolean performingConvert = ObjectUtils.equals(UpgradePage.class, pageClass); if (!performingUpgrade && !performingConvert) { if (!tm.containsOntology()) { // not an ontopoly topic map, so we'll have to redirect to the convert/upgrade page PageParameters pageParameters = new PageParameters(); pageParameters.put("topicMapId", topicMapId); throw new RestartResponseException(ConvertPage.class, pageParameters); } // if it is an old ontopoly topic map then do an upgrade if (!performingConvert) { float ontologyVersion = tm.getOntologyVersion(); if (ontologyVersion < OntopolyApplication.CURRENT_VERSION_NUMBER) { // not an ontopoly topic map, so we'll have to redirect to the upgrade page PageParameters pageParameters = new PageParameters(); pageParameters.put("topicMapId", topicMapId); throw new RestartResponseException(UpgradePage.class, pageParameters); } else if (ontologyVersion > OntopolyApplication.CURRENT_VERSION_NUMBER) { // FIXME: should create separate page for warning about future topic maps PageParameters pageParameters = new PageParameters(); pageParameters.put("message", "topicmap-is-created-by-a-newer-ontopoly"); setResponsePage(StartPage.class, pageParameters); setRedirect(true); } } } } return tm; } private TopicMapStoreIF createStore(String topicMapId, boolean readOnly, TopicMapRepositoryIF repository) { TopicMapReferenceIF ref = repository.getReferenceByKey(topicMapId); if (ref == null) throw new OntopiaRuntimeException("Topic map '" + topicMapId + "' not found in ontopoly repository."); try { return ref.createStore(readOnly); } catch (java.io.IOException e) { throw new OntopiaRuntimeException(e); } } }