added Clock and BinaryLight UPnP examples
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@399191 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Activator.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Activator.java
new file mode 100644
index 0000000..5b92db7
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Activator.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.upnp.UPnPDevice;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+public class Activator implements BundleActivator {
+
+ private ServiceRegistration serviceRegistration;
+ private BundleContext context;
+ private ClockFrame clockFrame;
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ this.context = context;
+ doServiceRegistration();
+ }
+
+ private void doServiceRegistration() {
+ clockFrame = new ClockFrame(context);
+ Dictionary dict = clockFrame.getClockDevice().getDescriptions(null);
+
+ serviceRegistration = context.registerService(
+ UPnPDevice.class.getName(),
+ clockFrame.getClockDevice(),
+ dict
+ );
+
+ clockFrame.start();
+
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ serviceRegistration.unregister();
+ clockFrame.stop();
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Clock.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Clock.java
new file mode 100644
index 0000000..294e637
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/Clock.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.util.Calendar;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class Clock
+{
+ private Calendar cal;
+
+ public Clock(Calendar cal)
+ {
+ this.cal = cal;
+ }
+
+ public Calendar getCalendar()
+ {
+ return cal;
+ }
+
+ ////////////////////////////////////////////////
+ // Time
+ ////////////////////////////////////////////////
+
+ public int getHour()
+ {
+ return getCalendar().get(Calendar.HOUR);
+ }
+
+ public int getMinute()
+ {
+ return getCalendar().get(Calendar.MINUTE);
+ }
+
+ public int getSecond()
+ {
+ return getCalendar().get(Calendar.SECOND);
+ }
+
+ ////////////////////////////////////////////////
+ // paint
+ ////////////////////////////////////////////////
+
+ public final static Clock getInstance()
+ {
+ return new Clock(Calendar.getInstance());
+ }
+
+ ////////////////////////////////////////////////
+ // getDateString
+ ////////////////////////////////////////////////
+
+ public final static String toClockString(int value)
+ {
+ if (value < 10)
+ return "0" + Integer.toString(value);
+ return Integer.toString(value);
+ }
+
+ private final static String MONTH_STRING[] = {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ };
+
+ public final static String toMonthString(int value)
+ {
+ value -= Calendar.JANUARY;
+ if (0 <= value && value < 12)
+ return MONTH_STRING[value];
+ return "";
+ }
+
+ private final static String WEEK_STRING[] = {
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ };
+
+ public final static String toWeekString(int value)
+ {
+ value -= Calendar.SUNDAY;
+ if (0 <= value && value < 7)
+ return WEEK_STRING[value];
+ return "";
+ }
+
+ public String getDateString()
+ {
+ Calendar cal = getCalendar();
+ return
+ toWeekString(cal.get(Calendar.DAY_OF_WEEK)) +", " +
+ toMonthString(cal.get(Calendar.MONTH)) + " " +
+ Integer.toString(cal.get(Calendar.DATE)) + ", " +
+ toClockString(cal.get(Calendar.YEAR) % 100);
+ }
+
+ ////////////////////////////////////////////////
+ // getTimeString
+ ////////////////////////////////////////////////
+
+ public String getTimeString()
+ {
+ Calendar cal = getCalendar();
+ return
+ toClockString(cal.get(Calendar.HOUR)) +
+ (((cal.get(Calendar.SECOND) % 2) == 0) ? ":" : " ") +
+ toClockString(cal.get(Calendar.MINUTE));
+ }
+
+ ////////////////////////////////////////////////
+ // toString
+ ////////////////////////////////////////////////
+
+ public String toString()
+ {
+ Calendar cal = getCalendar();
+ return
+ getDateString() + ", " +
+ toClockString(cal.get(Calendar.HOUR)) + ":" +
+ toClockString(cal.get(Calendar.MINUTE)) + ":" +
+ toClockString(cal.get(Calendar.SECOND));
+ }
+
+}
+
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockDevice.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockDevice.java
new file mode 100644
index 0000000..677975b
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockDevice.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+
+import java.beans.PropertyChangeEvent;
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.service.upnp.UPnPDevice;
+import org.osgi.service.upnp.UPnPIcon;
+import org.osgi.service.upnp.UPnPService;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class ClockDevice implements UPnPDevice {
+
+ final private String DEVICE_ID = "uuid:Felix-Clock";
+ private BundleContext context;
+ private TimerService timerService;
+ private UPnPService[] services;
+ private Dictionary dictionary;
+ UPnPEventNotifier notifier;
+
+ public ClockDevice(BundleContext context) {
+ this.context=context;
+ timerService = new TimerService();
+ services = new UPnPService[]{timerService};
+ setupDeviceProperties();
+ buildEventNotifyer();
+ }
+
+ /**
+ *
+ */
+ private void buildEventNotifyer() {
+ notifier = new UPnPEventNotifier(context,this,timerService,null);
+ }
+
+ private void setupDeviceProperties(){
+ dictionary = new Properties();
+ dictionary.put(UPnPDevice.UPNP_EXPORT,"");
+ dictionary.put(
+ org.osgi.service
+ .device.Constants.DEVICE_CATEGORY,
+ new String[]{UPnPDevice.DEVICE_CATEGORY}
+ );
+ //dictionary.put(UPnPDevice.DEVICE_CATEGORY,new String[]{UPnPDevice.DEVICE_CATEGORY});
+ dictionary.put(UPnPDevice.FRIENDLY_NAME,"Felix OSGi-UPnP Clock");
+ dictionary.put(UPnPDevice.MANUFACTURER,"Apache Software Foundation");
+ dictionary.put(UPnPDevice.MANUFACTURER_URL,"http://incubator.apache.org/felix/");
+ dictionary.put(UPnPDevice.MODEL_DESCRIPTION,"A CyberLink Clock device clone to test OSGi to UPnP service export");
+ dictionary.put(UPnPDevice.MODEL_NAME,"DolceDormire");
+ dictionary.put(UPnPDevice.MODEL_NUMBER,"1.0");
+ dictionary.put(UPnPDevice.MODEL_URL,"http://incubator.apache.org/felix/DolceDormire");
+ dictionary.put(UPnPDevice.PRESENTATION_URL,"http://incubator.apache.org/felix/dolceDormire/presentation");
+ dictionary.put(UPnPDevice.SERIAL_NUMBER,"123456789");
+ dictionary.put(UPnPDevice.TYPE,"urn:schemas-upnp-org:device:clock:1");
+ dictionary.put(UPnPDevice.UDN,DEVICE_ID);
+ //dictionary.put(UPnPDevice.ID,dictionary.get(UPnPDevice.UDN));
+ dictionary.put(UPnPDevice.UPC,"1213456789");
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPDevice#getService(java.lang.String)
+ */
+ public UPnPService getService(String serviceId) {
+ if (serviceId.equals(timerService.getId())) return timerService;
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPDevice#getServices()
+ */
+ public UPnPService[] getServices() {
+ return services;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPDevice#getIcons(java.lang.String)
+ */
+ public UPnPIcon[] getIcons(String locale) {
+ UPnPIcon icon = new ClockIcon();
+ return new UPnPIcon[]{icon} ;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPDevice#getDescriptions(java.lang.String)
+ */
+ public Dictionary getDescriptions(String locale) {
+ return dictionary;
+ }
+
+ /**
+ *
+ */
+ public void start() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ *
+ */
+ public void stop() {
+ notifier.destroy();
+ }
+
+ /**
+ *
+ */
+ public void update() {
+ Clock clock = Clock.getInstance();
+ String timeStr = clock.toString();
+ notifier.propertyChange(new PropertyChangeEvent(this,"Time","",timeStr));
+ }
+
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockFrame.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockFrame.java
new file mode 100644
index 0000000..a35dc38
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockFrame.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.awt.BorderLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.net.URL;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class ClockFrame extends JFrame implements Runnable
+{
+ private final static String TITLE = "Felix UPnP Clock";
+ private ClockDevice clockDev;
+ private ClockPane clockPane;
+
+ public ClockFrame(final BundleContext context)
+ {
+ super(TITLE);
+ try {
+ clockDev = new ClockDevice( context);
+ }
+ catch (Exception e) {
+ System.out.println(e);
+ }
+
+ getContentPane().setLayout(new BorderLayout());
+
+ clockPane = new ClockPane();
+ getContentPane().add(clockPane, BorderLayout.CENTER);
+
+ addWindowListener(new WindowAdapter(){
+ public void windowClosing(WindowEvent e)
+ {
+ try {
+ context.getBundle().stop();
+ } catch (BundleException ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ try {
+ URL eventIconUrl = ClockFrame.class.getResource("images/logo.gif");
+ ImageIcon icon= new ImageIcon(eventIconUrl,"logo");
+ setIconImage(icon.getImage());
+ }
+ catch (Exception ex){
+ System.out.println("Resource: IMAGES/logo.gif not found : " + ex.toString());
+ }
+
+ pack();
+ setVisible(true);
+ }
+
+ public ClockPane getClockPanel()
+ {
+ return clockPane;
+ }
+
+ public ClockDevice getClockDevice()
+ {
+ return clockDev;
+ }
+
+ ////////////////////////////////////////////////
+ // run
+ ////////////////////////////////////////////////
+
+ private Thread timerThread = null;
+
+ public void run()
+ {
+ Thread thisThread = Thread.currentThread();
+
+ while (timerThread == thisThread) {
+ getClockDevice().update();
+ getClockPanel().repaint();
+ try {
+ Thread.sleep(1000);
+ }
+ catch(InterruptedException e) {}
+ }
+ }
+
+ public void start()
+ {
+ clockDev.start();
+
+ timerThread = new Thread(this);
+ timerThread.start();
+ }
+
+ public void stop()
+ {
+ clockDev.stop();
+ timerThread = null;
+ dispose();
+ }
+
+}
+
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockIcon.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockIcon.java
new file mode 100644
index 0000000..53586be
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockIcon.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.osgi.service.upnp.UPnPIcon;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class ClockIcon implements UPnPIcon {
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getMimeType()
+ */
+ public String getMimeType() {
+ return "image/gif";
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getWidth()
+ */
+ public int getWidth() {
+ return 32;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getHeight()
+ */
+ public int getHeight() {
+ return 32;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getSize()
+ */
+ public int getSize() {
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getDepth()
+ */
+ public int getDepth() {
+ return 16;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPIcon#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return ClockIcon.class.getResourceAsStream("images/clock.gif");
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockPane.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockPane.java
new file mode 100644
index 0000000..3a9e232
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ClockPane.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+
+import javax.imageio.ImageIO;
+import javax.swing.JPanel;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class ClockPane extends JPanel // MouseListener
+{
+ public ClockPane()
+ {
+ loadImage();
+ initPanel();
+ }
+
+ ////////////////////////////////////////////////
+ // Background
+ ////////////////////////////////////////////////
+
+
+ private BufferedImage panelmage;
+
+ private void loadImage()
+ {
+
+ try {
+ panelmage = ImageIO.read(ClockPane.class.getResourceAsStream("images/clock.jpg"));
+ }
+ catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+
+ private BufferedImage getPaneImage()
+ {
+ return panelmage;
+ }
+
+ ////////////////////////////////////////////////
+ // Background
+ ////////////////////////////////////////////////
+
+ private void initPanel()
+ {
+ BufferedImage panelmage = getPaneImage();
+ setPreferredSize(new Dimension(panelmage.getWidth(), panelmage.getHeight()));
+ }
+
+ ////////////////////////////////////////////////
+ // Font
+ ////////////////////////////////////////////////
+
+ private final static String DEFAULT_FONT_NAME = "Lucida Console";
+ private final static int DEFAULT_TIME_FONT_SIZE = 60;
+ private final static int DEFAULT_DATE_FONT_SIZE = 18;
+ private final static int DEFAULT_SECOND_BLOCK_HEIGHT = 8;
+ private final static int DEFAULT_SECOND_BLOCK_FONT_SIZE = 10;
+
+ private Font timeFont = null;
+ private Font dateFont = null;
+ private Font secondFont = null;
+
+ private Font getFont(Graphics g, int size)
+ {
+ Font font = new Font(DEFAULT_FONT_NAME, Font.PLAIN, size);
+ if (font != null)
+ return font;
+ return g.getFont();
+ }
+
+ private Font getTimeFont(Graphics g)
+ {
+ if (timeFont == null)
+ timeFont = getFont(g, DEFAULT_TIME_FONT_SIZE);
+ return timeFont;
+ }
+
+ private Font getDateFont(Graphics g)
+ {
+ if (dateFont == null)
+ dateFont = getFont(g, DEFAULT_DATE_FONT_SIZE);
+ return dateFont;
+ }
+
+ private Font getSecondFont(Graphics g)
+ {
+ if (secondFont == null)
+ secondFont = getFont(g, DEFAULT_SECOND_BLOCK_FONT_SIZE);
+ return secondFont;
+ }
+
+ ////////////////////////////////////////////////
+ // paint
+ ////////////////////////////////////////////////
+
+ private void drawClockInfo(Graphics g)
+ {
+ Clock clock = Clock.getInstance();
+
+ int winWidth = getWidth();
+ int winHeight = getHeight();
+
+ g.setColor(Color.BLACK);
+
+ //// Time String ////
+
+ String timeStr = clock.getTimeString();
+
+ Font timeFont = getTimeFont(g);
+ g.setFont(timeFont);
+
+ FontMetrics timeFontMetric = g.getFontMetrics();
+ Rectangle2D timeStrBounds = timeFontMetric.getStringBounds(timeStr, g);
+
+ int timeStrWidth = (int)timeStrBounds.getWidth();
+ int timeStrHeight = (int)timeStrBounds.getHeight();
+ int timeStrX = (winWidth-timeStrWidth)/2;
+ int timeStrY = (winHeight+timeStrHeight)/2;
+ int timeStrOffset = timeStrHeight/8/2;
+ g.drawString(
+ timeStr,
+ timeStrX,
+ timeStrY);
+
+ //// Date String ////
+
+ String dateStr = clock.getDateString();
+
+ Font dateFont = getDateFont(g);
+ g.setFont(dateFont);
+
+ FontMetrics dateFontMetric = g.getFontMetrics();
+ Rectangle2D dateStrBounds = dateFontMetric.getStringBounds(dateStr, g);
+
+ g.drawString(
+ dateStr,
+ (winWidth-(int)dateStrBounds.getWidth())/2,
+ timeStrY-timeStrHeight-timeStrOffset);
+
+ //// Second Bar ////
+
+ Font secFont = getSecondFont(g);
+ g.setFont(secFont);
+ int sec = clock.getSecond();
+ int secBarBlockSize = timeStrWidth / 60;
+ int secBarBlockY = timeStrY + timeStrOffset;
+ for (int n=0; n<sec; n++) {
+ int x = timeStrX + (secBarBlockSize*n);
+ g.fillRect(
+ x,
+ secBarBlockY,
+ secBarBlockSize-1,
+ DEFAULT_SECOND_BLOCK_HEIGHT);
+ }
+ if (sec != 0 && (sec % 10) == 0) {
+ int x = timeStrX + (secBarBlockSize*sec);
+ g.drawString(
+ Integer.toString(sec),
+ x + secBarBlockSize,
+ secBarBlockY + DEFAULT_SECOND_BLOCK_HEIGHT);
+ }
+ }
+
+ private void clear(Graphics g)
+ {
+ g.setColor(Color.GRAY);
+ g.clearRect(0, 0, getWidth(), getHeight());
+ }
+
+
+ private void drawPanelImage(Graphics g)
+ {
+ g.drawImage(getPaneImage(), 0, 0, null);
+ }
+
+ public void paint(Graphics g)
+ {
+ clear(g);
+ drawPanelImage(g);
+ drawClockInfo(g);
+ }
+}
+
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/EventSource.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/EventSource.java
new file mode 100644
index 0000000..62fd7b1
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/EventSource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.beans.PropertyChangeListener;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public interface EventSource {
+ void addPropertyChangeListener(PropertyChangeListener listener);
+ void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
+ void removePropertyChangeListener(PropertyChangeListener listener);
+ void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
+}
+
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/GetTimeAction.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/GetTimeAction.java
new file mode 100644
index 0000000..d3d8728
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/GetTimeAction.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPStateVariable;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class GetTimeAction implements UPnPAction {
+
+ final private String NAME = "GetTime";
+ final private String RESULT_STATUS = "CurrentTime";
+ final private String[] OUT_ARG_NAMES = new String[]{RESULT_STATUS};
+ private TimeStateVariable time;
+
+
+ public GetTimeAction(TimeStateVariable time){
+ this.time = time;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getName()
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getReturnArgumentName()
+ */
+ public String getReturnArgumentName() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getInputArgumentNames()
+ */
+ public String[] getInputArgumentNames() {
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getOutputArgumentNames()
+ */
+ public String[] getOutputArgumentNames() {
+ return OUT_ARG_NAMES;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getStateVariable(java.lang.String)
+ */
+ public UPnPStateVariable getStateVariable(String argumentName) {
+ return time;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#invoke(java.util.Dictionary)
+ */
+ public Dictionary invoke(Dictionary args) throws Exception {
+ String value = time.getCurrentTime();
+ Hashtable result = new Hashtable();
+ result.put(RESULT_STATUS,value);
+ return result;
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ResultStateVariable.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ResultStateVariable.java
new file mode 100644
index 0000000..45983b8
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/ResultStateVariable.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+import org.osgi.service.upnp.UPnPStateVariable;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class ResultStateVariable implements UPnPStateVariable{
+
+ final private String NAME = "Result";
+ final private String DEFAULT_VALUE = "";
+ private Clock clock;
+
+
+ public ResultStateVariable(){
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getName()
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getJavaDataType()
+ */
+ public Class getJavaDataType() {
+ return String.class;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getUPnPDataType()
+ */
+ public String getUPnPDataType() {
+ return TYPE_STRING;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getDefaultValue()
+ */
+ public Object getDefaultValue() {
+ return DEFAULT_VALUE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getAllowedValues()
+ */
+ public String[] getAllowedValues() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getMinimum()
+ */
+ public Number getMinimum() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getMaximum()
+ */
+ public Number getMaximum() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getStep()
+ */
+ public Number getStep() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#sendsEvents()
+ */
+ public boolean sendsEvents() {
+ return false;
+ }
+
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/SetTimeAction.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/SetTimeAction.java
new file mode 100644
index 0000000..6312e02
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/SetTimeAction.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.util.Dictionary;
+
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPStateVariable;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class SetTimeAction implements UPnPAction {
+
+ final private String NAME = "SetTime";
+ final private String NEW_TIME_VALUE = "NewTime";
+ final private String NEW_RESULT_VALUE = "Result";
+ final private String[] IN_ARG_NAMES = new String[]{NEW_TIME_VALUE};
+ final private String[] OUT_ARG_NAMES = new String[]{NEW_RESULT_VALUE};
+ private UPnPStateVariable time,result;
+
+
+ public SetTimeAction(UPnPStateVariable time,UPnPStateVariable result){
+ this.time = time;
+ this.result=result;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getName()
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getReturnArgumentName()
+ */
+ public String getReturnArgumentName() {
+ return "Result";
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getInputArgumentNames()
+ */
+ public String[] getInputArgumentNames() {
+ return IN_ARG_NAMES;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getOutputArgumentNames()
+ */
+ public String[] getOutputArgumentNames() {
+ return OUT_ARG_NAMES;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPAction#getStateVariable(java.lang.String)
+ */
+ public UPnPStateVariable getStateVariable(String argumentName) {
+ if (argumentName.equals("NewTime")) return time;
+ else if (argumentName.equals("Result")) return result;
+ else return null;
+ }
+
+ /* (non-Javadoc)
+ *
+ * @see org.osgi.service.upnp.UPnPAction#invoke(java.util.Dictionary)
+ */
+ public Dictionary invoke(Dictionary args) throws Exception {
+ //Date value = (Date) args.get(NEW_TIME_VALUE);
+ long l = ((Long) args.get(NEW_TIME_VALUE)).longValue();
+ ((TimeStateVariable) time).setCurrentTime(l);
+ args.remove(NEW_TIME_VALUE);
+ args.put(NEW_RESULT_VALUE,((TimeStateVariable) time).getCurrentTime());
+ return args;
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimeStateVariable.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimeStateVariable.java
new file mode 100644
index 0000000..8ee30b5
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimeStateVariable.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+import org.osgi.service.upnp.UPnPStateVariable;
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class TimeStateVariable implements UPnPStateVariable{
+
+ final private String NAME = "Time";
+ final private String DEFAULT_VALUE = "";
+ private Clock clock;
+
+
+ public TimeStateVariable(){
+ clock = Clock.getInstance();
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getName()
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getJavaDataType()
+ */
+ public Class getJavaDataType() {
+ return Long.class;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getUPnPDataType()
+ */
+ public String getUPnPDataType() {
+ return TYPE_TIME;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getDefaultValue()
+ */
+ public Object getDefaultValue() {
+ return DEFAULT_VALUE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getAllowedValues()
+ */
+ public String[] getAllowedValues() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getMinimum()
+ */
+ public Number getMinimum() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getMaximum()
+ */
+ public Number getMaximum() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#getStep()
+ */
+ public Number getStep() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPStateVariable#sendsEvents()
+ */
+ public boolean sendsEvents() {
+ return true;
+ }
+
+ public String getCurrentTime(){
+ return clock.getTimeString();
+ }
+
+ public void setCurrentTime(long milliseconds){
+ clock.getCalendar().setTimeInMillis(milliseconds);
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimerService.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimerService.java
new file mode 100644
index 0000000..57927cf
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/TimerService.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.util.HashMap;
+
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPService;
+import org.osgi.service.upnp.UPnPStateVariable;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class TimerService implements UPnPService {
+ final private String SERVICE_ID = "urn:schemas-upnp-org:serviceId:timer:1";
+ final private String SERVICE_TYPE = "urn:schemas-upnp-org:service:timer:1";
+ final private String VERSION ="1";
+
+ private UPnPStateVariable time,result;
+ private UPnPStateVariable[] states;
+ private HashMap actions = new HashMap();
+
+
+ public TimerService(){
+ time = new TimeStateVariable();
+ result = new ResultStateVariable();
+ this.states = new UPnPStateVariable[]{time,result};
+
+ UPnPAction setTime= new SetTimeAction(time,result);
+ UPnPAction getTime = new GetTimeAction((TimeStateVariable)time);
+ actions.put(setTime.getName(),setTime);
+ actions.put(getTime.getName(),getTime);
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getId()
+ */
+ public String getId() {
+ return SERVICE_ID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getType()
+ */
+ public String getType() {
+ return SERVICE_TYPE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getVersion()
+ */
+ public String getVersion() {
+ return VERSION;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getAction(java.lang.String)
+ */
+ public UPnPAction getAction(String name) {
+ return (UPnPAction)actions.get(name);
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getActions()
+ */
+ public UPnPAction[] getActions() {
+ return (UPnPAction[])(actions.values()).toArray(new UPnPAction[]{});
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getStateVariables()
+ */
+ public UPnPStateVariable[] getStateVariables() {
+ return states;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.upnp.UPnPService#getStateVariable(java.lang.String)
+ */
+ public UPnPStateVariable getStateVariable(String name) {
+ if (name.equals("Time"))
+ return time;
+ else if (name.equals("Result"))
+ return result;
+ else return null;
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/UPnPEventNotifier.java b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/UPnPEventNotifier.java
new file mode 100644
index 0000000..b7c41df
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/java/org/apache/felix/upnp/sample/clock/UPnPEventNotifier.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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 org.apache.felix.upnp.sample.clock;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.upnp.UPnPDevice;
+import org.osgi.service.upnp.UPnPEventListener;
+import org.osgi.service.upnp.UPnPService;
+import org.osgi.service.upnp.UPnPStateVariable;
+
+/*
+* @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+*/
+
+public class UPnPEventNotifier implements PropertyChangeListener,ServiceListener {
+ BundleContext context;
+ UPnPDevice device;
+ UPnPService service;
+ EventSource source;
+
+ Properties UPnPTargetListener;
+ String deviceId;
+ String serviceId;
+ Vector upnpListeners = new Vector();
+
+ public UPnPEventNotifier(BundleContext context,UPnPDevice device,UPnPService service,EventSource source){
+ this.context=context;
+ this.device=device;
+ this.service=service;
+ this.source=source;
+ this.serviceId=service.getId();
+ setupUPnPListenerHouseKeeping(device);
+ }
+
+ /**
+ * @param deviceId
+ */
+ private void setupUPnPListenerHouseKeeping(UPnPDevice device) {
+ UPnPTargetListener = new Properties();
+ Dictionary dict = device.getDescriptions(null);
+ deviceId = (String) dict.get(UPnPDevice.ID);
+ UPnPTargetListener.put(UPnPDevice.ID,deviceId);
+ UPnPTargetListener.put(UPnPService.ID,serviceId);
+ UPnPTargetListener.put(UPnPDevice.TYPE,dict.get(UPnPDevice.TYPE));
+ UPnPTargetListener.put(UPnPService.TYPE,service.getType());
+ String ANY_UPnPEventListener = "("+Constants.OBJECTCLASS+"="+UPnPEventListener.class.getName()+")";
+
+ ServiceReference[] listeners = null;
+ try {
+ listeners = context.getServiceReferences(UPnPEventListener.class.getName(),null);
+ if (listeners != null){
+ for (int i = 0;i<listeners.length;i++){
+ ServiceReference sr = listeners[i];
+ Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);
+ if (filter == null) upnpListeners.add(sr);
+ else {
+ if (filter.match(UPnPTargetListener))
+ addNewListener(sr);
+ }
+ }
+ }
+ } catch (Exception ex) {
+ System.out.println(ex);
+ }
+
+ try {
+ //String filter = "(&" + ANY_UPnPEventListener + deviceId_Filter + ")";
+ String filter = ANY_UPnPEventListener;
+ context.addServiceListener(this,filter);
+ } catch (Exception ex) {
+ System.out.println(ex);
+ }
+
+ if (source!=null){
+ UPnPStateVariable[] vars = service.getStateVariables();
+ if (vars != null){
+ for (int i=0;i<vars.length;i++)
+ if(vars[i].sendsEvents())
+ source.addPropertyChangeListener(vars[i].getName(),this);
+ }
+ }
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent evt) {
+ Iterator list = upnpListeners.iterator();
+ String property = evt.getPropertyName();
+ Object value = evt.getNewValue();
+ String valueString = value.toString();
+ final Properties events = new Properties();
+ events.put(property,valueString);
+ while (list.hasNext()){
+ final ServiceReference sr = (ServiceReference)list.next();
+ String[] props =sr.getPropertyKeys();
+ new Thread(){
+ public void run(){
+ try {
+ UPnPEventListener listener = (UPnPEventListener) context.getService(sr);
+ listener.notifyUPnPEvent(deviceId,serviceId,events);
+ context.ungetService(sr);
+ } catch (Exception ex){
+ System.out.println("Clock UPnPEventNotifier Err: " +ex);
+ System.out.println("context: " +context);
+ System.out.println("listener: " +context.getService(sr));
+ System.out.println("sr: " +sr);
+ System.out.println();
+ }
+ }
+ }.start();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ */
+ public void serviceChanged(ServiceEvent e) {
+ switch(e.getType()){
+ case ServiceEvent.REGISTERED:{
+ ServiceReference sr = e.getServiceReference();
+ Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);
+ if (filter == null) addNewListener(sr);
+ else {
+ if (filter.match(UPnPTargetListener))
+ addNewListener(sr);
+ }
+ };break;
+
+ case ServiceEvent.MODIFIED:{
+ };break;
+
+ case ServiceEvent.UNREGISTERING:{
+ removeListener(e.getServiceReference());
+ };break;
+
+ }
+
+ }
+
+ /**
+ * @param reference
+ */
+ private void removeListener(ServiceReference reference) {
+ upnpListeners.remove(reference);
+ }
+
+ /**
+ * @param reference
+ */
+ private void addNewListener(ServiceReference reference) {
+ upnpListeners.add(reference);
+ }
+
+ public void destroy(){
+ context.removeServiceListener(this);
+ upnpListeners.removeAllElements();
+ }
+}
diff --git a/org.apache.felix.upnp.sample.clock/src/main/resources/META-INF/Manifest.mf b/org.apache.felix.upnp.sample.clock/src/main/resources/META-INF/Manifest.mf
new file mode 100644
index 0000000..69ff757
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/resources/META-INF/Manifest.mf
@@ -0,0 +1,4 @@
+Bundle-Author: Matteo Demuru <demuru@apache.org>,Francesco Furfari <furfari@apache.org>,Satoshi Konno <konno@users.sourceforge.
+ net>,Stefano "Kismet" Lenzi <lenzi@apache.org>
+Bundle-ClassPath: .
+
diff --git a/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.gif b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.gif
new file mode 100644
index 0000000..21327fc
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.gif
Binary files differ
diff --git a/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.jpg b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.jpg
new file mode 100644
index 0000000..f7fcea0
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/clock.jpg
Binary files differ
diff --git a/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/logo.gif b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/logo.gif
new file mode 100644
index 0000000..ef39d61
--- /dev/null
+++ b/org.apache.felix.upnp.sample.clock/src/main/resources/org/apache/felix/upnp/sample/clock/images/logo.gif
Binary files differ