| 1 | /* | |
| 2 | * Copyright 2019 Hector Espert <hectorespertpardo@gmail.com>. | |
| 3 | * | |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 | * you may not use this file except in compliance with the License. | |
| 6 | * You may obtain a copy of the License at | |
| 7 | * | |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 | * | |
| 10 | * Unless required by applicable law or agreed to in writing, software | |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 | * See the License for the specific language governing permissions and | |
| 14 | * limitations under the License. | |
| 15 | */ | |
| 16 | package es.blackleg.jlibnotify.core; | |
| 17 | ||
| 18 | import com.sun.jna.DefaultTypeMapper; | |
| 19 | import com.sun.jna.Library; | |
| 20 | import com.sun.jna.Native; | |
| 21 | import com.sun.jna.platform.EnumConverter; | |
| 22 | import es.blackleg.jlibnotify.exception.JLibnotifyLoadException; | |
| 23 | import es.blackleg.jlibnotify.jna.GBoolean; | |
| 24 | import java.util.HashMap; | |
| 25 | import java.util.Map; | |
| 26 | import es.blackleg.jlibnotify.JLibnotifyLoader; | |
| 27 | import es.blackleg.jlibnotify.JLibnotify; | |
| 28 | import es.blackleg.jlibnotify.jna.NativeLibnotify; | |
| 29 | ||
| 30 | /** | |
| 31 | * Reference implementation of {@link JLibnotifyLoader}, and the entry point of the library. | |
| 32 | * | |
| 33 | * <p>{@link #init()} builds a loader for the default library name, so a complete start looks | |
| 34 | * like:</p> | |
| 35 | * | |
| 36 | * <pre>{@code | |
| 37 | * JLibnotify jLibnotify = DefaultJLibnotifyLoader.init().load(); | |
| 38 | * jLibnotify.init("My Application"); | |
| 39 | * }</pre> | |
| 40 | * | |
| 41 | * <p>This is the only class of {@link es.blackleg.jlibnotify.core} application code is expected to | |
| 42 | * name; everything else is reached through the interfaces of {@link es.blackleg.jlibnotify}.</p> | |
| 43 | * | |
| 44 | * @author Hector Espert | |
| 45 | */ | |
| 46 | public class DefaultJLibnotifyLoader implements JLibnotifyLoader { | |
| 47 | ||
| 48 | /** | |
| 49 | * Name of the shared library loaded when none is given: version 4 of libnotify. | |
| 50 | */ | |
| 51 | private static final String DEFAULT_LIBRARY_NAME = "libnotify.so.4"; | |
| 52 | ||
| 53 | private final String libraryName; | |
| 54 | ||
| 55 | private final ServerCapabilitiesReader serverCapabilitiesReader; | |
| 56 | ||
| 57 | /** | |
| 58 | * Creates a loader for the default library name, {@code libnotify.so.4}. | |
| 59 | */ | |
| 60 | public DefaultJLibnotifyLoader() { | |
| 61 | this(DEFAULT_LIBRARY_NAME); | |
| 62 | } | |
| 63 | ||
| 64 | /** | |
| 65 | * Creates a loader for a given library name. | |
| 66 | * | |
| 67 | * <p>Useful to load another version of libnotify, or a copy of it installed outside the | |
| 68 | * standard library path.</p> | |
| 69 | * | |
| 70 | * @param libraryName name of the shared library, as understood by | |
| 71 | * {@link com.sun.jna.Native#load(String, Class, Map)} | |
| 72 | */ | |
| 73 | public DefaultJLibnotifyLoader(String libraryName) { | |
| 74 | this(libraryName, new DefaultServerCapabilitiesReader()); | |
| 75 | } | |
| 76 | ||
| 77 | /** | |
| 78 | * Creates a loader for a given library name and capabilities reader. | |
| 79 | * | |
| 80 | * @param libraryName name of the shared library, as understood by | |
| 81 | * {@link com.sun.jna.Native#load(String, Class, Map)} | |
| 82 | * @param serverCapabilitiesReader reader the loaded library will use to walk the capabilities | |
| 83 | * returned by the notification server | |
| 84 | */ | |
| 85 | public DefaultJLibnotifyLoader(String libraryName, ServerCapabilitiesReader serverCapabilitiesReader) { | |
| 86 | this.libraryName = libraryName; | |
| 87 | this.serverCapabilitiesReader = serverCapabilitiesReader; | |
| 88 | } | |
| 89 | ||
| 90 | /** | |
| 91 | * Loads the native library and binds it to a {@link DefaultJLibnotify}. | |
| 92 | * | |
| 93 | * <p>Registers a type mapper converting the C {@code gboolean} results into {@link GBoolean} | |
| 94 | * before handing the interface to JNA. Native loading fails with an {@link Error} rather than | |
| 95 | * an exception, so every {@link Throwable} is caught and reported as a checked | |
| 96 | * {@link JLibnotifyLoadException}.</p> | |
| 97 | * | |
| 98 | * @return a binding of the loaded library, not yet initialised | |
| 99 | * @throws JLibnotifyLoadException if the library is missing or cannot be loaded, which is the | |
| 100 | * case on any platform other than Linux | |
| 101 | */ | |
| 102 | @Override | |
| 103 | public JLibnotify load() throws JLibnotifyLoadException { | |
| 104 | try { | |
| 105 | EnumConverter enumConverter = new EnumConverter(GBoolean.class); | |
| 106 | DefaultTypeMapper defaultTypeMapper = new DefaultTypeMapper(); | |
| 107 |
1
1. load : removed call to com/sun/jna/DefaultTypeMapper::addTypeConverter → NO_COVERAGE |
defaultTypeMapper.addTypeConverter(GBoolean.class, enumConverter); |
| 108 | Map<String, Object> options = new HashMap<>(); | |
| 109 | options.put(Library.OPTION_TYPE_MAPPER, defaultTypeMapper); | |
| 110 | NativeLibnotify nativeLibNotify = Native.load(this.libraryName, NativeLibnotify.class, options); | |
| 111 |
1
1. load : replaced return value with null for es/blackleg/jlibnotify/core/DefaultJLibnotifyLoader::load → NO_COVERAGE |
return new DefaultJLibnotify(nativeLibNotify, this.serverCapabilitiesReader); |
| 112 | } catch (Throwable throwable) { | |
| 113 | throw new JLibnotifyLoadException(String.format("Unable to load %s library", this.libraryName), throwable); | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | /** | |
| 118 | * Creates a loader for the default library name, {@code libnotify.so.4}. | |
| 119 | * | |
| 120 | * <p>Starting point of the library, meant to be chained with {@link #load()}.</p> | |
| 121 | * | |
| 122 | * @return a loader ready to load the default libnotify library | |
| 123 | */ | |
| 124 | public static JLibnotifyLoader init() { | |
| 125 |
1
1. init : replaced return value with null for es/blackleg/jlibnotify/core/DefaultJLibnotifyLoader::init → NO_COVERAGE |
return new DefaultJLibnotifyLoader(); |
| 126 | } | |
| 127 | ||
| 128 | } | |
Mutations | ||
| 107 |
1.1 |
|
| 111 |
1.1 |
|
| 125 |
1.1 |