Java tutorial
/* * Copyright (C) 2010 Stanford University * * 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 edu.stanford.junction; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import org.json.JSONObject; import edu.stanford.junction.api.activity.ActivityScript; import edu.stanford.junction.api.activity.Cast; import edu.stanford.junction.api.activity.JunctionActor; import edu.stanford.junction.api.messaging.MessageHeader; import edu.stanford.junction.JunctionException; import edu.stanford.junction.provider.JunctionProvider; import edu.stanford.junction.provider.jvm.JVMSwitchboardConfig; import edu.stanford.junction.provider.jx.JXSwitchboardConfig; import edu.stanford.junction.provider.xmpp.XMPPSwitchboardConfig; import edu.stanford.junction.provider.irc.IRCSwitchboardConfig; /** * This class creates {@link Junction} objects, binding {@link JunctionActor} * objects to an activity. */ public class JunctionMaker { public static final String DIRECTOR_ACTIVITY = "edu.stanford.junction.director"; public static final URI CASTING_DIRECTOR = URI.create("junction://jx-director-local/cast"); protected JunctionProvider mProvider; public static final URI SWITCHBOARD_ACTIVITY = URI.create("junction://sb.openjunction.org/switchboard"); /** * Returns a new {@link JunctionMaker} object with the type specified * by the given {@link SwitchboardConfig} object. */ public static JunctionMaker getInstance(SwitchboardConfig switchboardConfig) { // TODO: map config to maker? JunctionMaker maker = new JunctionMaker(); maker.mProvider = maker.getProvider(switchboardConfig); maker.mProvider.setJunctionMaker(maker); return maker; } public static String getSessionIDFromURI(URI uri) { try { return uri.getPath().substring(1); } catch (Exception e) { return null; } } public JunctionMaker() { } /** * Binds a {@link JunctionActor} to a session URI, using the default * switchboard for that URI. */ public static Junction bind(URI uri, JunctionActor actor) throws JunctionException { return JunctionMaker.getInstance(JunctionMaker.getDefaultSwitchboardConfig(uri)).newJunction(uri, actor); } /** * Binds a {@link JunctionActor} to a randomly generated sesssion, using the default * switchboard. */ public static Junction bind(JunctionActor actor) throws JunctionException { // default SwitchboardConfig config = new XMPPSwitchboardConfig("prpl.stanford.edu"); JunctionMaker maker = JunctionMaker.getInstance(config); return maker.newJunction(maker.generateSessionUri(), actor); } protected JunctionProvider getProvider(SwitchboardConfig switchboardConfig) { if (switchboardConfig instanceof XMPPSwitchboardConfig) { return new edu.stanford.junction.provider.xmpp.JunctionProvider( (XMPPSwitchboardConfig) switchboardConfig); } else if (switchboardConfig instanceof JVMSwitchboardConfig) { return new edu.stanford.junction.provider.jvm.JunctionProvider( (JVMSwitchboardConfig) switchboardConfig); } else if (switchboardConfig instanceof JXSwitchboardConfig) { return new edu.stanford.junction.provider.jx.JunctionProvider((JXSwitchboardConfig) switchboardConfig); } else if (switchboardConfig instanceof IRCSwitchboardConfig) { return new edu.stanford.junction.provider.irc.JunctionProvider( (IRCSwitchboardConfig) switchboardConfig); } else { // Unknown implementation;. return null; } } /* * JunctionMaker has three functions: * (1) Connect an Actor to a Junction * (2) Retrieve an activity's script given a URI * (3) Support various invitation mechanisms (often platform-specific) */ /** * This method has been deprecated. Please see * {@link newJunction(URI, ActivityScript, JunctionActor)} */ public Junction newJunction(URI uri, JunctionActor actor) throws JunctionException { return mProvider.newJunction(uri, null, actor); } @Deprecated public Junction newJunction(URI uri, ActivityScript script, JunctionActor actor) throws JunctionException { return mProvider.newJunction(uri, script, actor); } @Deprecated public Junction newJunction(ActivityScript desc, JunctionActor actor) throws JunctionException { URI sessionUri; if (desc == null) { desc = new ActivityScript(); } if (desc.getSessionID() == null) { sessionUri = mProvider.generateSessionUri(); desc.isActivityCreator(true); desc.setUri(sessionUri); } else { // TODO: get rid of this. try { sessionUri = new URI("junction://" + desc.getHost() + "/" + desc.getSessionID()); } catch (URISyntaxException e) { throw new IllegalArgumentException("Bad URI from activity script"); } } return mProvider.newJunction(sessionUri, desc, actor); } public URI generateSessionUri() { return mProvider.generateSessionUri(); } /** * Creates a new Junction and requests the casting of various roles. * There is no guarantee if and when the roles will be filled. * There may or may not be user interaction at the casting director. * * @param desc * @param actor * @param support * @return */ public Junction newJunction(ActivityScript desc, JunctionActor actor, Cast support) throws JunctionException { Junction jx = newJunction(desc, actor); //System.out.println("creating activity " + desc.getJSON()); int size = support.size(); System.out.println("going to cast " + size + " roles"); for (int i = 0; i < size; i++) { if (support.getDirector(i) != null) { //System.out.println("Casting role " + support.getRole(i) + " on " + support.getDirector(i)); URI invitationURI = jx.getInvitationURI(support.getRole(i)); this.castActor(support.getDirector(i), invitationURI); } } return jx; } /** * Sends a message to an activity. In the * unoptimized case, joins an activity, sends * a message, and leaves. * * @param activitySession * @param msg */ public void sendMessageToActivity(URI activitySession, JSONObject msg) throws JunctionException { mProvider.sendMessageToActivity(activitySession, msg); } public ActivityScript getActivityScript(URI uri) throws JunctionException { return mProvider.getActivityScript(uri); } /** * Sends a request to a Director activity * to cast an actor to accept a given invitation. * * @param directorURI The director listening for requests * @param invitationURI The activity to join (potentially including role information) */ public void castActor(final URI directorURI, final URI invitationURI) throws JunctionException { JunctionActor actor = new JunctionActor("inviter") { @Override public void onActivityJoin() { JSONObject invitation = new JSONObject(); try { invitation.put("action", "cast"); invitation.put("activity", invitationURI.toString()); getJunction().sendMessageToSession(invitation); } catch (Exception e) { e.printStackTrace(System.err); } leave(); } @Override public void onMessageReceived(MessageHeader header, JSONObject message) { } }; JunctionMaker.this.newJunction(directorURI, actor); } /** * Returns the role associated with a given Junction invitation. * @param uri * @return */ public static String getRoleFromInvitation(URI uri) { String query = uri.getQuery(); if (query == null) return null; int pos = query.indexOf("role="); if (pos == -1) { return null; } query = query.substring(pos + 5); pos = query.indexOf('&'); if (pos > -1) { query = query.substring(0, pos); } return query; } @Deprecated public void inviteActorByListenerService(final URI invitationURI, URI listenerServiceURI) throws JunctionException { JunctionActor actor = new JunctionActor("inviter") { @Override public void onActivityJoin() { JSONObject invitation = new JSONObject(); try { invitation.put("activity", invitationURI.toString()); getJunction().sendMessageToSession(invitation); } catch (Exception e) { e.printStackTrace(System.err); } leave(); } @Override public void onMessageReceived(MessageHeader header, JSONObject message) { } }; JunctionMaker.this.newJunction(listenerServiceURI, actor); } /** * Requests a listening service to join this activity as the prescribed role. Here, * the service must be detailed in the activity description's list of roles. * * An example platform in the role specification: * { role: "dealer", platforms: [ * { platform: "jxservice", * classname: "edu.stanford.prpl.poker.dealer", * switchboard: "my.foreign.switchboard" } ] } * * If switchboard is not present, it is assumed to be on the same switchboard * on which this activity is being run. * * @param role * @param host * @param serviceName */ @Deprecated public void inviteActorService(final Junction jx, final String role) throws JunctionException { ActivityScript desc = jx.getActivityScript(); System.out.println("Desc: " + desc.getJSON().toString()); // find service platform spec System.out.println("inviting service for role " + role); JSONObject platform = desc.getRolePlatform(role, "jxservice"); System.out.println("got platform " + platform); if (platform == null) return; String switchboard = platform.optString("switchboard"); System.out.println("switchboard: " + switchboard); if (switchboard == null || switchboard.length() == 0) { switchboard = jx.getSwitchboard(); System.out.println("switchboard is null, new: " + switchboard); } final String serviceName = platform.optString("serviceName"); // // // // // // // // // // // // // // // // JunctionActor actor = new JunctionActor("inviter") { @Override public void onActivityJoin() { JSONObject invitation = new JSONObject(); try { invitation.put("activity", jx.getInvitationURI(role)); invitation.put("serviceName", serviceName); } catch (Exception e) { } getJunction().sendMessageToSession(invitation); leave(); } @Override public void onMessageReceived(MessageHeader header, JSONObject message) { } }; // remote jxservice activity: URI remoteServiceActivity = null; try { remoteServiceActivity = new URI("junction://" + switchboard + "/jxservice"); } catch (URISyntaxException e) { e.printStackTrace(); return; } System.out.println("Inviting service at uri " + remoteServiceActivity); JunctionMaker.this.newJunction(remoteServiceActivity, actor); } public static SwitchboardConfig getDefaultSwitchboardConfig(URI uri) { String fragment = uri.getFragment(); if (fragment == null) { fragment = "xmpp"; } fragment = fragment.toLowerCase(); if (fragment.equals("jvm")) { return new edu.stanford.junction.provider.jvm.JVMSwitchboardConfig(); } else if (fragment.equals("jx")) { return new edu.stanford.junction.provider.jx.JXSwitchboardConfig(); } else if (fragment.equals("jx")) { return new edu.stanford.junction.provider.jx.JXSwitchboardConfig(); } else if (fragment.equals("irc")) { return new edu.stanford.junction.provider.irc.IRCSwitchboardConfig(); } // assume xmpp return new edu.stanford.junction.provider.xmpp.XMPPSwitchboardConfig(uri); } }