/** @param t */ public static synchronized void remove(Trigger t) { int preSize = TriggerPersistence.size(); try { t.unregister(); list.remove(t); int postSize = TriggerPersistence.size(); if (!(postSize == (preSize - 1))) { LOG.severe("Error while while removing trigger '" + t.getName() + "'"); } } catch (Exception e) { LOG.severe("Error while while unregistering the trigger '" + t.getName() + "'"); } }
protected Object unmarshalFromInputStream( Unmarshaller unmarshaller, InputStream is, Annotation[] anns, MediaType mt) throws JAXBException { // Try to create the read before unmarshalling the stream XMLStreamReader xmlReader = null; try { if (is == null) { Reader reader = getStreamHandlerFromCurrentMessage(Reader.class); if (reader == null) { LOG.severe("No InputStream, Reader, or XMLStreamReader is available"); throw ExceptionUtils.toInternalServerErrorException(null, null); } xmlReader = StaxUtils.createXMLStreamReader(reader); } else { xmlReader = StaxUtils.createXMLStreamReader(is); } configureReaderRestrictions(xmlReader); return unmarshaller.unmarshal(xmlReader); } finally { try { StaxUtils.close(xmlReader); } catch (XMLStreamException e) { // Ignore } } }
@Override public String getNetworkEndpoint() { try { VdeNetworkEndpoint localEndpoint = new VdeNetworkEndpoint( NetworkUtils.getHostAddress().getHostAddress(), this.tempDir.toPath().resolve("sockets").toString(), null); return localEndpoint.value(); } catch (JAXBException e) { LOG.severe("Could not marshal network endpoint information."); e.printStackTrace(); // TODO throw BWFLAException return null; } catch (Exception e) { LOG.severe("Could not determine public IP address."); e.printStackTrace(); return null; } }
protected void marshalToOutputStream( Marshaller ms, Object obj, OutputStream os, Annotation[] anns, MediaType mt) throws Exception { if (os == null) { Writer writer = getStreamHandlerFromCurrentMessage(Writer.class); if (writer == null) { LOG.severe("No OutputStream, Writer, or XMLStreamWriter is available"); throw ExceptionUtils.toInternalServerErrorException(null, null); } ms.marshal(obj, writer); writer.flush(); } else { ms.marshal(obj, os); } }
private static boolean registerModule( Path pythonModuleRoot, String pythonModuleName, final String pythonClassName) { String pythonModuleRelPath = pythonModuleName.replace('.', '/'); Path pythonModuleFile = pythonModuleRoot.resolve(pythonModuleRelPath + ".py"); if (!Files.exists(pythonModuleFile)) { LOG.severe(String.format("Missing Python module '%s'", pythonModuleFile.toUri())); return false; } Path pythonInfoXmlFile = pythonModuleRoot.resolve(pythonModuleRelPath + "-info.xml"); if (!Files.exists(pythonInfoXmlFile)) { LOG.warning( String.format( "Missing operator metadata file '%s'. Using defaults.", pythonInfoXmlFile.toUri())); } DefaultOperatorDescriptor operatorDescriptor = createOperatorDescriptor(pythonInfoXmlFile, pythonModuleName); File pythonModuleRootFile = FileUtils.toFile(pythonModuleRoot); PyOperatorSpi operatorSpi = new PyOperatorSpi(operatorDescriptor) { @Override public Operator createOperator() throws OperatorException { PyOperator pyOperator = (PyOperator) super.createOperator(); pyOperator.setParameterDefaultValues(); pyOperator.setPythonModulePath(pythonModuleRootFile.getPath()); pyOperator.setPythonModuleName(pythonModuleName); pyOperator.setPythonClassName(pythonClassName); return pyOperator; } }; String operatorName = operatorDescriptor.getAlias() != null ? operatorDescriptor.getAlias() : operatorDescriptor.getName(); GPF.getDefaultInstance().getOperatorSpiRegistry().addOperatorSpi(operatorName, operatorSpi); LOG.info( String.format( "Python operator '%s' registered (Python module: '%s', class: '%s', root: '%s')", operatorName, pythonModuleName, pythonClassName, pythonModuleRootFile)); return true; }
@Override public void destroy() { runner.stop(); runner.cleanup(); // remove temporary dir if (tempDir != null && tempDir.exists()) { try { FileUtils.deleteDirectory(tempDir); LOG.info("Temporary directory removed: " + tempDir.getAbsolutePath()); tempDir = null; } catch (IOException e) { LOG.severe(e.getMessage()); } } }
/** @param t */ public static synchronized void addAndRegister(Trigger t) { int preSize = TriggerPersistence.size(); if (!list.contains(t)) { list.add(t); t.register(); int postSize = TriggerPersistence.size(); if (!(postSize == (preSize + 1))) { LOG.severe("Error while while adding and registering trigger '" + t.getName() + "'"); } } else { // this trigger is already in the list int old = list.indexOf(t); list.get(old).unregister(); list.set(old, t); t.register(); } }
/** @param folder */ public static void saveTriggers(File folder) { if (list.isEmpty()) { LOG.warning( "There are no triggers to persist, " + folder.getAbsolutePath() + " will not be altered."); return; } if (!folder.isDirectory()) { LOG.warning(folder.getAbsoluteFile() + " is not a valid trigger folder. Skipped"); return; } XStream xstream = FreedomXStream.getXstream(); deleteTriggerFiles(folder); try { LOG.config("Saving triggers to file in " + folder.getAbsolutePath()); for (Trigger trigger : list) { if (trigger.isToPersist()) { String uuid = trigger.getUUID(); if ((uuid == null) || uuid.isEmpty()) { trigger.setUUID(UUID.randomUUID().toString()); } String fileName = trigger.getUUID() + ".xtrg"; FileWriter fstream = new FileWriter(folder + "/" + fileName); BufferedWriter out = new BufferedWriter(fstream); out.write(xstream.toXML(trigger)); // persist only the data not the logic // Close the output stream out.close(); fstream.close(); } } } catch (Exception e) { LOG.info(e.getLocalizedMessage()); LOG.severe(Freedomotic.getStackTraceInfo(e)); } }
private static DefaultOperatorDescriptor createOperatorDescriptor( Path pythonInfoXmlFile, String pythonModuleName) { DefaultOperatorDescriptor operatorDescriptor; if (Files.exists(pythonInfoXmlFile)) { try { try (BufferedReader reader = Files.newBufferedReader(pythonInfoXmlFile)) { operatorDescriptor = DefaultOperatorDescriptor.fromXml( reader, pythonInfoXmlFile.toUri().toString(), PyOperatorSpi.class.getClassLoader()); } } catch (IOException e) { LOG.severe(String.format("Failed to read from '%s'", pythonInfoXmlFile)); operatorDescriptor = null; } } else { operatorDescriptor = new DefaultOperatorDescriptor(pythonModuleName, PyOperator.class); } return operatorDescriptor; }
/** @param folder */ public static synchronized void loadTriggers(File folder) { XStream xstream = FreedomXStream.getXstream(); // This filter only returns object files FileFilter objectFileFileter = new FileFilter() { public boolean accept(File file) { if (file.isFile() && file.getName().endsWith(".xtrg")) { return true; } else { return false; } } }; File[] files = folder.listFiles(objectFileFileter); try { StringBuilder summary = new StringBuilder(); // print an header for the index.txt file summary.append("#Filename \t\t #TriggerName \t\t\t #ListenedChannel").append("\n"); if (files != null) { for (File file : files) { Trigger trigger = null; try { // validate the object against a predefined DTD String xml = DOMValidateDTD.validate( file, Info.getApplicationPath() + "/config/validator/trigger.dtd"); trigger = (Trigger) xstream.fromXML(xml); } catch (Exception e) { LOG.log( Level.SEVERE, "Trigger file {0} is not well formatted: {1}", new Object[] {file.getPath(), e.getLocalizedMessage()}); continue; } // addAndRegister trigger to the list if it is not a duplicate if (!list.contains(trigger)) { if (trigger.isHardwareLevel()) { trigger.setPersistence(false); // it has not to me stored in root/data folder addAndRegister(trigger); // in the list and start listening } else { if (folder.getAbsolutePath().startsWith(Info.getPluginsPath())) { trigger.setPersistence(false); } else { trigger.setPersistence(true); // not hardware trigger and not plugin related } list.add( trigger); // only in the list not registred. I will be registred only if used in // mapping } } else { LOG.warning("Trigger '" + trigger.getName() + "' is already in the list"); } summary .append(trigger.getUUID()) .append("\t\t") .append(trigger.getName()) .append("\t\t\t") .append(trigger.getChannel()) .append("\n"); } // writing a summary .txt file with the list of commands in this folder FileWriter fstream = new FileWriter(folder + "/index.txt"); BufferedWriter indexfile = new BufferedWriter(fstream); indexfile.write(summary.toString()); // Close the output stream indexfile.close(); } else { LOG.config("No triggers to load from this folder " + folder.toString()); } } catch (Exception e) { LOG.severe("Exception while loading this trigger.\n" + Freedomotic.getStackTraceInfo(e)); } }
/** * Append the range [off, off+len) from the provided sample data to the line. * * @param samples sample data * @param off sample data offset * @param len sample data length */ private void appendFrames(final byte[] samples, int off, int len) { assert off % bytesPerFrame == 0; assert len % bytesPerFrame == 0; /* Make sure that [off, off+len) does not exceed sample's bounds */ off = Math.min(off, (samples != null) ? samples.length : 0); len = Math.min(len, (samples != null) ? samples.length - off : 0); if (len <= 0) { return; } /* Convert samples if necessary */ final byte[] samplesConverted = Arrays.copyOfRange(samples, off, off + len); if (convertUnsignedToSigned) { /* The line expects signed PCM samples, so we must * convert the unsigned PCM samples to signed. * Note that this only affects the high bytes! */ for (int i = 0; i < samplesConverted.length; i += 2) { samplesConverted[i] = (byte) ((samplesConverted[i] & 0xff) - 0x80); } } /* Write samples to line */ // final int bytesWritten = m_line.write(samplesConverted, 0, samplesConverted.length); final int bytesWritten = audioTrack.write(samplesConverted, 0, samplesConverted.length); if (bytesWritten == AudioTrack.ERROR_INVALID_OPERATION) { LOG.severe("Audio Track not initialized properly"); throw new RuntimeException( "Audio Track not initialized properly: AudioTrack status: ERROR_INVALID_OPERATION"); } else if (bytesWritten == AudioTrack.ERROR_BAD_VALUE) { LOG.severe("Wrong parameters sent to Audio Track!"); throw new RuntimeException( "Wrong parameters sent to Audio Track! AudioTrack status: ERROR_BAD_VALUE"); } else if (bytesWritten != len) { LOG.warning( "Audio output line accepted only " + bytesWritten + " bytes of sample data while trying to write " + samples.length + " bytes"); } else { LOG.info(bytesWritten + " bytes written to the audio output line"); } /* Update state */ synchronized (AudioOutputQueue.this) { framesWrittenToLine += (bytesWritten / bytesPerFrame); for (int b = 0; b < bytesPerFrame; ++b) { lineLastFrame[b] = samples[off + len - (bytesPerFrame - b)]; } if (LOG.isLoggable(Level.FINE)) { LOG.finest( "Audio output line end is now at " + getNextLineTime() + " after writing " + len / bytesPerFrame + " frames"); } } }
/** Enqueuer thread main method */ @Override public void run() { try { /* Mute line initially to prevent clicks */ setVolume(Float.NEGATIVE_INFINITY); /* Start the line */ // m_line.start(); // start the audio track audioTrack.play(); LOG.info("Audio Track started !!!"); boolean lineMuted = true; boolean didWarnGap = false; while (!closing) { if (!frameQueue.isEmpty()) { /* Queue filled */ /* If the gap between the next packet and the end of line is * negligible (less than one packet), we write it to the line. * Otherwise, we fill the line buffer with silence and hope for * further packets to appear in the queue */ final long entryFrameTime = frameQueue.firstKey(); final long entryLineTime = convertFrameToLineTime(entryFrameTime); final long gapFrames = entryLineTime - getNextLineTime(); // LOG.info("** gapFrames: " + gapFrames + " packetSizeFrames: " + packetSizeFrames); if (gapFrames < -packetSizeFrames) { /* Too late for playback */ LOG.warning( "Audio data was scheduled for playback " + (-gapFrames) + " frames ago, skipping"); frameQueue.remove(entryFrameTime); continue; } else if (gapFrames < packetSizeFrames) { /* Negligible gap between packet and line end. Prepare packet for playback */ didWarnGap = false; /* Unmute line in case it was muted previously */ if (lineMuted) { LOG.info("Audio data available, un-muting line"); lineMuted = false; applyVolume(); } else if (getVolume() != getRequestedVolume()) { applyVolume(); } /* Get sample data and do sanity checks */ final byte[] nextPlaybackSamples = frameQueue.remove(entryFrameTime); int nextPlaybackSamplesLength = nextPlaybackSamples.length; if (nextPlaybackSamplesLength % bytesPerFrame != 0) { LOG.severe( "Audio data contains non-integral number of frames, ignore last " + (nextPlaybackSamplesLength % bytesPerFrame) + " bytes"); nextPlaybackSamplesLength -= nextPlaybackSamplesLength % bytesPerFrame; } /* Append packet to line */ LOG.finest( "Audio data containing " + nextPlaybackSamplesLength / bytesPerFrame + " frames for playback time " + entryFrameTime + " found in queue, appending to the output line"); appendFrames(nextPlaybackSamples, 0, nextPlaybackSamplesLength, entryLineTime); continue; } else { /* Gap between packet and line end. Warn */ if (!didWarnGap) { didWarnGap = true; LOG.warning( "Audio data missing for frame time " + getNextLineTime() + " (currently " + gapFrames + " frames), writing " + packetSizeFrames + " frames of silence"); } } } else { /* Queue empty */ if (!lineMuted) { lineMuted = true; setVolume(Float.NEGATIVE_INFINITY); LOG.fine( "Audio data ended at frame time " + getNextLineTime() + ", writing " + packetSizeFrames + " frames of silence and muted line"); } } appendSilence(packetSizeFrames); } // TODO: I don't think we need the appendSilence anymore when using Android API, but will // evaluate that later during tests /* Before we exit, we fill the line's buffer with silence. This should prevent * noise from being output while the line is being stopped */ // appendSilence(m_line.available() / m_bytesPerFrame); } catch (final Throwable e) { LOG.log(Level.SEVERE, "Audio output thread died unexpectedly", e); } finally { setVolume(Float.NEGATIVE_INFINITY); audioTrack.stop(); audioTrack.release(); // m_line.stop(); // m_line.close(); } }