com.oracle.dio.registry.RegistryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.openjdk.dio Show documentation
Show all versions of org.openjdk.dio Show documentation
Maven/OSGi repackaging of OpenJDK's Device I/O library
The newest version!
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.dio.registry;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import com.oracle.dio.impl.PeripheralDescriptorImpl;
import com.oracle.dio.utils.Configuration;
import com.oracle.dio.utils.Constants;
import jdk.dio.Device;
import jdk.dio.DeviceConfig;
import jdk.dio.DeviceDescriptor;
import jdk.dio.DeviceMgmtPermission;
import jdk.dio.UnsupportedDeviceTypeException;
class RegistryImpl extends Registry {
private static final String REGISTRY_FILE_PATH = "jdk.dio.registry";
private static final String PREDEFINED = "predefined";
private static final String DEFAULT_CHARSET_NAME = "UTF-8";
protected static final boolean canRegister = true;
private WeakReference registryCache;
private WeakReference contentCache;
@Override
public synchronized DeviceDescriptor super T> get(int id) {
Properties registry = loadRegistry();
RegistryContent content = readRegistryContent(registry);
return createDescriptor(id, content);
}
@Override
public synchronized Iterator> get(String name, Class intf, String... properties) {
return createDescriptorList(name, intf, properties);
}
@Override
public synchronized int register(PeripheralDescriptorImpl super T> descriptor)
throws UnsupportedOperationException, IOException {
int id = super.register(descriptor);
Class extends Device> intf = descriptor.getInterface();
Properties registry = loadRegistry();
RegistryContent content = readRegistryContent(registry);
String factory = DeviceRegistryFactory.registryFactoryName(intf);
if (factory == null) {
throw new UnsupportedDeviceTypeException("Unsupported type: " + intf.getName());
}
RegistryData data = null;
try {
data = ((DeviceRegistryFactory)Class.forName(factory).newInstance()).createRegistryData(descriptor);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new UnsupportedDeviceTypeException("Unsupported type: " + intf.getName());
}
content.put(id, data);
registry.setProperty(Integer.toString(id), data.toString());
try {
saveRegistry(registry);
} catch (Exception e) {
content.remove(id);
registry.remove(Integer.toString(id));
throw e;
}
return id;
}
@Override
public synchronized DeviceDescriptor unregister(int id) {
Registry.checkPermission(null, id, DeviceMgmtPermission.UNREGISTER);
Registry.checkID(id);
Properties registry = loadRegistry();
RegistryContent content = readRegistryContent(registry);
RegistryData config = content.get(id);
DeviceDescriptor d = createDescriptor(id, content);
if (config == null) {
return null;
}
if (config.getBooleanProperty(PREDEFINED, false)) {
throw new IllegalArgumentException("Device cannot be unregistered");
}
content.remove(id);
registry.remove(Integer.toString(id));
try {
saveRegistry(registry);
} catch (IOException e) {
}
return d;
}
@Override
public synchronized Iterator> list(Class intf) {
return createDescriptorList(null, intf);
}
private Properties loadRegistry() {
Properties registry = null;
if (registryCache != null) {
registry = registryCache.get();
}
if (registry == null) {
registry = new Properties();
final Properties reg = registry;
final String path = Configuration.getSystemProperty(REGISTRY_FILE_PATH);
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
if (path != null) {
reg.load(new InputStreamReader(new FileInputStream(path), DEFAULT_CHARSET_NAME));
}
} catch (IOException | SecurityException | IllegalArgumentException e) {
reg.clear();
}
return null;
}
});
registryCache = new WeakReference(registry);
}
return registry;
}
private void saveRegistry(Properties registry) throws IOException {
final String path = Configuration.getSystemProperty(REGISTRY_FILE_PATH);
if (path == null) {
throw new IOException("Registry is not available");
}
final Properties reg = registry;
try {
AccessController.doPrivileged(new PrivilegedExceptionAction(){
public Object run() throws IOException {
reg.store(new OutputStreamWriter(new FileOutputStream(path), DEFAULT_CHARSET_NAME), null);
return null;
}
});
} catch(PrivilegedActionException e) {
throw (IOException)e.getException();
}
}
private RegistryContent readRegistryContent(Properties registry) {
RegistryContent content = null;
if (contentCache != null) {
content = contentCache.get();
}
if (content == null) {
content = new RegistryContent();
Enumeration> names = registry.propertyNames();
while (names.hasMoreElements()) {
String name = (String)names.nextElement();
if (!name.isEmpty()) {
String value = registry.getProperty(name);
processProperty(name, value, content);
}
}
contentCache = new WeakReference(content);
}
return content;
}
private void processProperty(String name, String value, RegistryContent content) {
try {
int id = Integer.parseInt(name);
processEntryProperty(id, value, content);
} catch(NumberFormatException e) {
processTypeProperty(name, value, content);
}
}
private void processEntryProperty(int id, String value, RegistryContent content) {
RegistryData data = new RegistryData();
parseBlock(value, data);
if (!data.isEmpty()) {
content.put(id, data);
}
}
private void processTypeProperty(String name, String value, RegistryContent content) {
RegistryData data = new RegistryData();
parseBlock(value, data);
if (!data.isEmpty()) {
content.putType(name, data);
}
}
private static void parseBlock(String block, RegistryData data) {
while (true) {
int inc = 2, pos = block.indexOf("\\:");
if (pos == -1) {
inc = 1; pos = block.indexOf(':');
if (pos == -1) {
break;
}
}
String key = block.substring(0, pos).trim();
block = block.substring(pos + inc).trim();
if (block.charAt(0) == '[') {
int end = block.indexOf(']');
if (end == -1) {
break;
}
RegistryList list = new RegistryList();
parseList(block.substring(1, end).trim(), list);
if (!list.isEmpty()) {
data.putListProperty(key, list);
}
pos = block.indexOf(',', end + 1);
if (pos == -1) {
break;
}
block = block.substring(pos + 1).trim();
} else {
int end = block.indexOf(',');
String value;
if (end == -1) {
value = block;
block = "";
} else {
value = block.substring(0, end).trim();
block = block.substring(end + 1).trim();
}
if (!value.isEmpty()) {
data.putCharacterProperty(key, value);
}
}
}
}
private static void parseList(String block, RegistryList list) {
while (!block.isEmpty()) {
if (block.charAt(0) == '{') {
int pos = block.indexOf('}');
if (pos == -1) {
break;
}
RegistryData data = new RegistryData();
parseBlock(block.substring(1, pos), data);
if (!data.isEmpty()) {
list.add(data);
}
int end = block.indexOf(',', pos + 1);
if (end == -1) {
break;
}
block = block.substring(end + 1).trim();
} else if (block.charAt(0) == '\"') {
int pos = block.indexOf('\"', 1);
if (pos == -1) {
break;
}
String value = block.substring(1, pos).trim();
if (!value.isEmpty()) {
list.add(value);
}
int end = block.indexOf(',', pos);
if (end == -1) {
break;
}
block = block.substring(end + 1).trim();
} else {
break;
}
}
}
private DeviceDescriptor createDescriptor(int id, RegistryContent content) {
RegistryData config = content.get(id);
if (config == null) {
return null;
}
String type = config.getCharacterProperty(DeviceRegistryFactory.DEVICE_TYPE);
if (type == null) {
return null;
}
String factory = DeviceRegistryFactory.registryFactoryName(type);
if (factory == null) {
return null;
}
RegistryData defaults = content.getType(type);
if (defaults != null) {
config = config.cloneRegistryData();
Enumeration keys = defaults.keys();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
if (!config.hasProperty(key)) {
config.copyProperty(key, defaults);
}
}
}
try {
return ((DeviceRegistryFactory)Class.forName(factory).newInstance()).createDeviceDescriptor(id, config);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException | IOException e) {
return null;
}
}
private Iterator> createDescriptorList(String name, Class intf, String... properties) {
Collection> result = new Vector<>();
Properties registry = loadRegistry();
RegistryContent content = readRegistryContent(registry);
Enumeration entries = content.entries();
while (entries.hasMoreElements()) {
int id = entries.nextElement().intValue();
RegistryData config = content.get(id);
if (intf != null) {
String deviceType = config.getCharacterProperty(DeviceRegistryFactory.DEVICE_TYPE);
if (deviceType == null || intf.getName().indexOf(deviceType) == -1) {
continue;
}
}
if (name != null) {
String deviceName = config.getCharacterProperty(Constants.NAME);
if (deviceName == null || !deviceName.equals(name)) {
continue;
}
}
DeviceDescriptor super T> descriptor = createDescriptor(id, content);
if (descriptor == null) {
continue;
}
if (properties != null && properties.length > 0) {
String[] descriptorProps = descriptor.getProperties();
if (descriptorProps == null || descriptorProps.length == 0) {
continue;
}
boolean match = true;
for (int i = 0; match && (i < properties.length); i++) {
match = false;
for (int j = 0; j < descriptorProps.length; j++) {
if (properties[i].equalsIgnoreCase(descriptorProps[j])) {
match = true;
break;
}
}
}
if (!match) {
continue;
}
}
result.add(descriptor);
}
return result.iterator();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy