Java tutorial
/* * Copyright (C) 2011 Stanford University MobiSocial Lab * http://mobisocial.stanford.edu * * 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 mobisocial.nfcserver; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URI; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.apache.commons.codec.binary.Base64; import mobisocial.ndefexchange.ConnectionHandoverManager; import mobisocial.nfc.NdefHandler; import mobisocial.nfc.NfcInterface; import mobisocial.nfc.PrioritizedHandler; import mobisocial.nfc.ShareHandler; import mobisocial.nfcserver.handler.AppManifestHandler; import mobisocial.nfcserver.handler.EchoNdefHandler; import mobisocial.nfcserver.handler.HttpFileHandler; import mobisocial.nfcserver.handler.HttpUrlHandler; import mobisocial.nfcserver.handler.LogNdefHandler; import mobisocial.nfcserver.handler.MimeTypeHandler; import mobisocial.nfcserver.handler.NdefExchangeHandoverHandler; import mobisocial.nfcserver.handler.share.LocalFileToMime; import mobisocial.nfcserver.handler.share.NdefToNfc; import mobisocial.nfcserver.handler.share.ParseLine; import mobisocial.nfcserver.handler.share.TextToNdef; import mobisocial.nfcserver.handler.share.UriToNdef; import mobisocial.nfcserver.impl.BluetoothNdefServer; import mobisocial.nfcserver.impl.JunctionNdefServer; import mobisocial.nfcserver.impl.TcpNdefServer; import mobisocial.util.QR; import android.nfc.NdefMessage; import android.nfc.NdefRecord; public class DesktopNfcServer implements NfcInterface { public static DesktopNfcServer sInstance; private final Map<Integer, Set<NdefHandler>> mNdefHandlers = new TreeMap<Integer, Set<NdefHandler>>(); private final Map<Integer, Set<ShareHandler>> mShareHandlers = new TreeMap<Integer, Set<ShareHandler>>(); private NdefMessage mForegroundNdef = null; private boolean ECHO_NDEF = true; public interface Contract { public void start(); public void stop(); public String getHandoverUrl(); } private static final String TAG = "nfcserver"; static DesktopNfcServer sNdefProxy; public static void main(String[] args) { try { Contract server; if (args.length > 0 && args[0].equals("tcp")) { // recoverable failure; if args is null, length == 0. server = new TcpNdefServer(args); } else if (args.length > 0 && args[0].equals("junction")) { server = new JunctionNdefServer(args); } else { server = new BluetoothNdefServer(args); //Builder<BluetoothNdefServer>().build(); } String content = ConnectionHandoverManager.USER_HANDOVER_PREFIX + Base64.encodeBase64URLSafeString(getHandoverNdef(server.getHandoverUrl()).toByteArray()); System.out.println("Welcome to DesktopNfc!"); System.out.println("Service running on " + server.getHandoverUrl()); System.out.println("Your configuration QR is: " + QR.getQrl(content)); // QRL server.start(); NfcInterface nfc = getInstance(); final String PROMPT = "> "; BufferedReader lineReader = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.print(PROMPT); String line = lineReader.readLine().trim(); nfc.share(line); } } catch (Exception e) { e.printStackTrace(); } } private DesktopNfcServer() { addDefaultNdefHandlers(); } public static NfcInterface getInstance() { if (sInstance == null) { sInstance = new DesktopNfcServer(); } return sInstance; } public void addNdefHandler(NdefHandler handler) { if (handler instanceof PrioritizedHandler) { addNdefHandler(((PrioritizedHandler) handler).getPriority(), handler); } else { addNdefHandler(PrioritizedHandler.DEFAULT_PRIORITY, handler); } } public synchronized void addNdefHandler(Integer priority, NdefHandler handler) { if (!mNdefHandlers.containsKey(priority)) { mNdefHandlers.put(priority, new LinkedHashSet<NdefHandler>()); } Set<NdefHandler> handlers = mNdefHandlers.get(priority); handlers.add(handler); } public void addShareHandler(ShareHandler handler) { if (handler instanceof PrioritizedHandler) { addShareHandler(((PrioritizedHandler) handler).getPriority(), handler); } else { addShareHandler(PrioritizedHandler.DEFAULT_PRIORITY, handler); } } public synchronized void addShareHandler(Integer priority, ShareHandler handler) { if (!mShareHandlers.containsKey(priority)) { mShareHandlers.put(priority, new LinkedHashSet<ShareHandler>()); } Set<ShareHandler> handlers = mShareHandlers.get(priority); handlers.add(handler); } public synchronized void handleNdef(NdefMessage[] ndef) { Iterator<Integer> bins = mNdefHandlers.keySet().iterator(); while (bins.hasNext()) { Integer priority = bins.next(); Iterator<NdefHandler> handlers = mNdefHandlers.get(priority).iterator(); while (handlers.hasNext()) { NdefHandler handler = handlers.next(); if (handler.handleNdef(ndef) == NdefHandler.NDEF_CONSUME) { return; } } } } //@Override public void setForegroundNdefMessage(final NdefMessage ndef) { /* ImutableNdef */ mForegroundNdef = ndef; } public void share(Object shared) { Iterator<Integer> bins = mShareHandlers.keySet().iterator(); while (bins.hasNext()) { Integer priority = bins.next(); Iterator<ShareHandler> handlers = mShareHandlers.get(priority).iterator(); while (handlers.hasNext()) { ShareHandler handler = handlers.next(); shared = handler.handleShare(shared); } } } //@Override public NdefMessage getForegroundNdefMessage() { return mForegroundNdef; } private static NdefMessage getHandoverNdef(String ref) { NdefRecord[] records = new NdefRecord[3]; /* Handover Request */ byte[] version = new byte[] { (0x1 << 4) | (0x2) }; records[0] = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_HANDOVER_REQUEST, new byte[0], version); /* Collision Resolution */ records[1] = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, new byte[] { 0x63, 0x72 }, new byte[0], new byte[] { 0x0, 0x0 }); /* Handover record */ byte[] payload = new byte[ref.length() + 1]; System.arraycopy(ref.getBytes(), 0, payload, 1, ref.length()); records[2] = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload); return new NdefMessage(records); } private void addDefaultNdefHandlers() { addNdefHandler(new LogNdefHandler()); addNdefHandler(new MimeTypeHandler()); addNdefHandler(new HttpUrlHandler()); addNdefHandler(new HttpFileHandler()); addNdefHandler(new AppManifestHandler()); if (ECHO_NDEF) { addNdefHandler(new EchoNdefHandler(this)); } addShareHandler(new ParseLine()); addShareHandler(new TextToNdef()); addShareHandler(new UriToNdef()); addShareHandler(new LocalFileToMime()); addShareHandler(new NdefToNfc(this)); NdefExchangeHandoverHandler.prepare(this); } }