001/* 002 * Copyright (c) 1998-2012 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: barseghian $' 006 * '$Date: 2012-04-27 13:16:27 -0700 (Fri, 27 Apr 2012) $' 007 * '$Revision: 29789 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler.data.datasource.dataone; 030 031import java.io.IOException; 032import java.io.InputStream; 033 034import org.apache.commons.io.IOUtils; 035import org.apache.log4j.Logger; 036import org.dataone.client.CNode; 037import org.dataone.client.D1Client; 038import org.dataone.client.MNode; 039import org.dataone.service.exceptions.InsufficientResources; 040import org.dataone.service.exceptions.InvalidToken; 041import org.dataone.service.exceptions.NotAuthorized; 042import org.dataone.service.exceptions.NotFound; 043import org.dataone.service.exceptions.NotImplemented; 044import org.dataone.service.exceptions.ServiceFailure; 045import org.dataone.service.types.v1.Identifier; 046import org.dataone.service.types.v1.ObjectFormatIdentifier; 047import org.dataone.service.types.v1.ObjectLocation; 048import org.dataone.service.types.v1.ObjectLocationList; 049import org.dataone.service.types.v1.SystemMetadata; 050import org.ecoinformatics.seek.datasource.DataSourceIcon; 051 052import ptolemy.actor.TypedIOPort; 053import ptolemy.actor.lib.LimitedFiringSource; 054import ptolemy.actor.parameters.PortParameter; 055import ptolemy.data.ArrayToken; 056import ptolemy.data.StringToken; 057import ptolemy.data.Token; 058import ptolemy.data.UnsignedByteToken; 059import ptolemy.data.expr.StringParameter; 060import ptolemy.data.type.ArrayType; 061import ptolemy.data.type.BaseType; 062import ptolemy.kernel.CompositeEntity; 063import ptolemy.kernel.util.IllegalActionException; 064import ptolemy.kernel.util.NameDuplicationException; 065 066/** 067 * @author Derik Barseghian 068 * @version $Id: DataOneActor.java 29789 2012-04-27 20:16:27Z barseghian $ 069 */ 070public class DataOneActor extends LimitedFiringSource { 071 072 private static final Logger logger = Logger.getLogger(DataOneActor.class); 073 private DataSourceIcon _icon; 074 private StringParameter nodeIdStringParameter; 075 private PortParameter pidPortParam; 076 077 /** 078 * Output sensorNameOutputPort 079 * 080 * @UserLevelDocumentation The sensor name after parsing sensorId 081 */ 082 public TypedIOPort formatIdOutputPort; 083 084 public DataOneActor(CompositeEntity container, String name) 085 throws NameDuplicationException, IllegalActionException { 086 super(container, name); 087 088 _icon = new DataSourceIcon(this); 089 090 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 091 + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n" 092 + "</svg>\n"); 093 094 pidPortParam = new PortParameter(this, "PID"); 095 pidPortParam.setStringMode(true); 096 pidPortParam.setTypeEquals(BaseType.STRING); 097 pidPortParam.getPort().setTypeEquals(BaseType.STRING); 098 099 // output.setDisplayName("output"); 100 output.setTypeEquals(new ArrayType(BaseType.UNSIGNED_BYTE)); 101 formatIdOutputPort = new TypedIOPort(this, "Format Id", false, true); 102 formatIdOutputPort.setTypeEquals(BaseType.STRING); 103 } 104 105 public void fire() throws IllegalActionException { 106 super.fire(); 107 _icon.setBusy(); 108 109 try { 110 CNode cNode = D1Client.getCN(); 111 112 Identifier pid = new Identifier(); 113 pidPortParam.update(); 114 if (pidPortParam.getToken() != null) { 115 pid.setValue(((StringToken) pidPortParam.getToken()) 116 .stringValue()); 117 } 118 119 // Only attempt to fetch pid if necessary 120 if (output.numberOfSinks() > 0 && pid.getValue() != null 121 && !pid.getValue().equals("")) { 122 123 ObjectLocationList objectLocationList = cNode.resolve(pid); 124 125 // XXX Instead of first, use a specific node based on some 126 // criteria? 127 ObjectLocation objectLocation = objectLocationList 128 .getObjectLocation(0); 129 MNode mnNode = D1Client.getMN(objectLocation 130 .getNodeIdentifier()); 131 InputStream inputStream = mnNode.get(pid); 132 byte[] bytes = IOUtils.toByteArray(inputStream); 133 logger.debug(" for pid:" + pid.getValue() + " got " 134 + bytes.length + " bytes."); 135 String formatId = "unknown"; 136 SystemMetadata sysMeta = mnNode.getSystemMetadata(pid); 137 138 if (sysMeta != null) { 139 ObjectFormatIdentifier objectFormat = sysMeta.getFormatId(); 140 if (objectFormat != null) { 141 formatId = objectFormat.getValue(); 142 } 143 } 144 // System.out.println("=====the format identifier is "+formatId); 145 // XXX ByteArrayToken offers less overhead 146 // but currently in ptolemy-excludes 147 // ByteArrayToken token = new ByteArrayToken(); 148 Token byteTokens[] = new Token[bytes.length]; 149 for (int i = 0; i < bytes.length; i++) { 150 byteTokens[i] = new UnsignedByteToken(bytes[i]); 151 } 152 output.broadcast(new ArrayToken(byteTokens)); 153 formatIdOutputPort.send(0, new StringToken(formatId)); 154 } 155 156 } catch (InvalidToken e) { 157 // TODO Auto-generated catch block 158 e.printStackTrace(); 159 throw new IllegalActionException("InvalidToken: " + e.getDescription()); 160 } catch (NotAuthorized e) { 161 // TODO Auto-generated catch block 162 e.printStackTrace(); 163 throw new IllegalActionException("NotAuthorized: " + e.getDescription()); 164 } catch (NotImplemented e) { 165 // TODO Auto-generated catch block 166 e.printStackTrace(); 167 throw new IllegalActionException("NotImplemented: " + e.getDescription()); 168 } catch (ServiceFailure e) { 169 // TODO Auto-generated catch block 170 e.printStackTrace(); 171 throw new IllegalActionException("ServiceFailure: " + e.getDescription()); 172 } catch (NotFound e) { 173 // TODO Auto-generated catch block 174 e.printStackTrace(); 175 throw new IllegalActionException("NotFound: " + e.getDescription()); 176 } catch (IOException e) { 177 // TODO Auto-generated catch block 178 e.printStackTrace(); 179 throw new IllegalActionException("IOException: " + e.toString()); 180 } catch (InsufficientResources e) { 181 // TODO Auto-generated catch block 182 e.printStackTrace(); 183 throw new IllegalActionException("InsufficientResources: " + e.toString()); 184 } finally { 185 _icon.setReady(); 186 } 187 188 _icon.setReady(); 189 } 190 191 public void preinitialize() throws IllegalActionException { 192 super.preinitialize(); 193 } 194 195 /** The director told us to stop firing immediately. */ 196 public void stop() { 197 super.stop(); 198 _icon.setReady(); 199 } 200 201 public void wrapup() throws IllegalActionException { 202 super.wrapup(); 203 } 204 205}