001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.scxml2; 018 019import java.io.Serializable; 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.HashSet; 024import java.util.Map; 025import java.util.Set; 026 027/** 028 * The SCXMLSystemContext is used as a read only Context wrapper 029 * and provides the SCXML (read only) system variables which are injected via the unwrapped {@link #getContext()}. 030 * 031 * @see <a href="http://www.w3.org/TR/scxml/#SystemVariables">http://www.w3.org/TR/scxml/#SystemVariables</a> 032 */ 033public class SCXMLSystemContext implements Context, Serializable { 034 035 /** 036 * Serial version UID. 037 */ 038 private static final long serialVersionUID = 1L; 039 040 /** 041 * The protected system variables names as defined in the SCXML specification 042 * @see <a href="http://www.w3.org/TR/scxml/#SystemVariables">http://www.w3.org/TR/scxml/#SystemVariables</a> 043 */ 044 public static final String EVENT_KEY = "_event"; 045 public static final String SESSIONID_KEY = "_sessionid"; 046 public static final String SCXML_NAME_KEY = "_name"; 047 public static final String IOPROCESSORS_KEY = "_ioprocessors"; 048 public static final String X_KEY = "_x"; 049 050 /** The Commons SCXML internal {@link #getPlatformVariables() platform variable key} holding the current SCXML 051 * status instance **/ 052 public static final String STATUS_KEY = "status"; 053 054 /** 055 * The set of protected system variables names 056 */ 057 private static final Set<String> PROTECTED_NAMES = new HashSet<String>(Arrays.asList( 058 new String[] {EVENT_KEY, SESSIONID_KEY, SCXML_NAME_KEY, IOPROCESSORS_KEY, X_KEY} 059 )); 060 061 /** 062 * The wrapped system context 063 */ 064 065 private Context systemContext; 066 067 /** 068 * The auto-generated next sessionId prefixed ID 069 * @see #generateSessionId() 070 */ 071 private long nextSessionSequenceId; 072 073 /** 074 * Initialize or replace systemContext 075 * @param systemContext the system context to set 076 * @throws java.lang.NullPointerException if systemContext == null 077 */ 078 void setSystemContext(Context systemContext) { 079 if (this.systemContext != null) { 080 // replace systemContext 081 systemContext.getVars().putAll(this.systemContext.getVars()); 082 } 083 else { 084 // create Platform variables map 085 systemContext.setLocal(X_KEY, new HashMap<String, Object>()); 086 } 087 this.systemContext = systemContext; 088 this.protectedVars = Collections.unmodifiableMap(systemContext.getVars()); 089 } 090 091 /** 092 * The unmodifiable wrapped variables map from the wrapped system context 093 */ 094 private Map<String, Object> protectedVars; 095 096 public SCXMLSystemContext(Context systemContext) { 097 setSystemContext(systemContext); 098 } 099 100 public String generateSessionId() { 101 return getContext().get(SESSIONID_KEY) + "-" + nextSessionSequenceId++; 102 } 103 104 @Override 105 public void set(final String name, final Object value) { 106 if (PROTECTED_NAMES.contains(name)) { 107 throw new UnsupportedOperationException(); 108 } 109 // non-protected variables are set on the parent of the system context (e.g. root context) 110 systemContext.getParent().set(name, value); 111 } 112 113 @Override 114 public void setLocal(final String name, final Object value) { 115 throw new UnsupportedOperationException(); 116 } 117 118 @Override 119 public Object get(final String name) { 120 return systemContext.get(name); 121 } 122 123 @Override 124 public boolean has(final String name) { 125 return systemContext.has(name); 126 } 127 128 @Override 129 public boolean hasLocal(final String name) { 130 return systemContext.hasLocal(name); 131 } 132 133 @Override 134 public Map<String, Object> getVars() { 135 return protectedVars; 136 } 137 138 @Override 139 public void reset() { 140 throw new UnsupportedOperationException(); 141 } 142 143 @Override 144 public Context getParent() { 145 return systemContext.getParent(); 146 } 147 148 @Override 149 public SCXMLSystemContext getSystemContext() { 150 return this; 151 } 152 153 /** 154 * @return The Platform specific system variables map stored under the {@link #X_KEY _x} root system variable 155 */ 156 @SuppressWarnings("unchecked") 157 public Map<String, Object> getPlatformVariables() { 158 return (Map<String, Object>)get(X_KEY); 159 } 160 161 /** 162 * @return Returns the wrapped (modifiable) system context 163 */ 164 Context getContext() { 165 return systemContext; 166 } 167}