1 /*
2  * libosinfo:
3  *
4  * Copyright (C) 2009-2020 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <osinfo/osinfo.h>
22 #include <glib/gi18n-lib.h>
23 
24 /**
25  * SECTION:osinfo_devicelinkfilter
26  * @short_description: an operating system filter
27  * @see_also: #OsinfoFilter, #OsinfoDeviceLink
28  *
29  * #OsinfoDeviceLinkFilter is a specialization of #OsinfoFilter that
30  * can also set a constraint against the device link target.
31  * It can only be used to filter entities
32  * that are #OsinfoDeviceLink objects.
33  */
34 
35 struct _OsinfoDeviceLinkFilterPrivate
36 {
37     OsinfoFilter *targetFilter;
38 };
39 
40 G_DEFINE_TYPE_WITH_PRIVATE(OsinfoDeviceLinkFilter, osinfo_devicelinkfilter, OSINFO_TYPE_FILTER);
41 
42 static gboolean osinfo_devicelinkfilter_matches_default(OsinfoFilter *devicelinkfilter, OsinfoEntity *entity);
43 
44 enum {
45     PROP_0,
46 
47     PROP_TARGET_FILTER,
48 
49     LAST_PROP
50 };
51 static GParamSpec *properties[LAST_PROP];
52 
53 static void
osinfo_devicelinkfilter_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)54 osinfo_devicelinkfilter_set_property(GObject *object,
55                                      guint property_id,
56                                      const GValue *value,
57                                      GParamSpec *pspec)
58 {
59     OsinfoDeviceLinkFilter *filter = OSINFO_DEVICELINKFILTER(object);
60 
61     switch (property_id)
62         {
63         case PROP_TARGET_FILTER:
64             if (filter->priv->targetFilter)
65                 g_object_unref(filter->priv->targetFilter);
66             filter->priv->targetFilter = g_value_get_object(value);
67             if (filter->priv->targetFilter)
68                 g_object_ref(filter->priv->targetFilter);
69             break;
70         default:
71             /* We don't have any other property... */
72             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
73             break;
74         }
75 }
76 
77 static void
osinfo_devicelinkfilter_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)78 osinfo_devicelinkfilter_get_property(GObject *object,
79                                      guint property_id,
80                                      GValue *value,
81                                      GParamSpec *pspec)
82 {
83     OsinfoDeviceLinkFilter *filter = OSINFO_DEVICELINKFILTER(object);
84 
85     switch (property_id)
86         {
87         case PROP_TARGET_FILTER:
88             g_value_set_object(value, filter->priv->targetFilter);
89             break;
90         default:
91             /* We don't have any other property... */
92             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
93             break;
94         }
95 }
96 
97 
98 static void
osinfo_devicelinkfilter_finalize(GObject * object)99 osinfo_devicelinkfilter_finalize(GObject *object)
100 {
101     OsinfoDeviceLinkFilter *filter = OSINFO_DEVICELINKFILTER(object);
102 
103     g_object_unref(filter->priv->targetFilter);
104 
105     /* Chain up to the parent class */
106     G_OBJECT_CLASS(osinfo_devicelinkfilter_parent_class)->finalize(object);
107 }
108 
109 /* Init functions */
110 static void
osinfo_devicelinkfilter_class_init(OsinfoDeviceLinkFilterClass * klass)111 osinfo_devicelinkfilter_class_init(OsinfoDeviceLinkFilterClass *klass)
112 {
113     GObjectClass *g_klass = G_OBJECT_CLASS(klass);
114     OsinfoFilterClass *filter_klass = OSINFO_FILTER_CLASS(klass);
115 
116     g_klass->finalize = osinfo_devicelinkfilter_finalize;
117     g_klass->set_property = osinfo_devicelinkfilter_set_property;
118     g_klass->get_property = osinfo_devicelinkfilter_get_property;
119 
120     /**
121      * OsinfoDeviceLinkFilter:target-filter:
122      *
123      * The operating system to be deployed
124      */
125     properties[PROP_TARGET_FILTER] = g_param_spec_object("target-filter",
126                                                          "Target Filter",
127                                                          _("Device link target filter"),
128                                                          OSINFO_TYPE_FILTER,
129                                                          G_PARAM_CONSTRUCT_ONLY |
130                                                          G_PARAM_READWRITE |
131                                                          G_PARAM_STATIC_STRINGS);
132     g_object_class_install_properties(g_klass, LAST_PROP, properties);
133 
134     filter_klass->matches = osinfo_devicelinkfilter_matches_default;
135 }
136 
137 
138 /**
139  * osinfo_devicelinkfilter_new:
140  * @filter: the target device filter
141  *
142  * Construct a new filter that matches all operating
143  * systems
144  *
145  * Returns: (transfer full): a new filter
146  */
osinfo_devicelinkfilter_new(OsinfoFilter * filter)147 OsinfoDeviceLinkFilter *osinfo_devicelinkfilter_new(OsinfoFilter *filter)
148 {
149     return g_object_new(OSINFO_TYPE_DEVICELINKFILTER,
150                         "target-filter", filter,
151                         NULL);
152 }
153 
154 
155 static void
osinfo_devicelinkfilter_init(OsinfoDeviceLinkFilter * devicelinkfilter)156 osinfo_devicelinkfilter_init(OsinfoDeviceLinkFilter *devicelinkfilter)
157 {
158     devicelinkfilter->priv = osinfo_devicelinkfilter_get_instance_private(devicelinkfilter);
159 }
160 
161 
162 /**
163  * osinfo_devicelinkfilter_get_target_filter:
164  * @filter: the filter object
165  *
166  * Retrieve the filter used to match against the target of
167  * the device link
168  *
169  * Returns: (transfer none): the target filter object
170  */
osinfo_devicelinkfilter_get_target_filter(OsinfoDeviceLinkFilter * filter)171 OsinfoFilter *osinfo_devicelinkfilter_get_target_filter(OsinfoDeviceLinkFilter *filter)
172 {
173     g_return_val_if_fail(OSINFO_IS_DEVICELINKFILTER(filter), NULL);
174 
175     return filter->priv->targetFilter;
176 }
177 
178 
osinfo_devicelinkfilter_matches_default(OsinfoFilter * filter,OsinfoEntity * entity)179 static gboolean osinfo_devicelinkfilter_matches_default(OsinfoFilter *filter, OsinfoEntity *entity)
180 {
181     OsinfoDeviceLinkFilter *linkfilter;
182 
183     g_return_val_if_fail(OSINFO_IS_DEVICELINKFILTER(filter), FALSE);
184     g_return_val_if_fail(OSINFO_IS_DEVICELINK(entity), FALSE);
185 
186     linkfilter = OSINFO_DEVICELINKFILTER(filter);
187 
188     if (!OSINFO_FILTER_CLASS(osinfo_devicelinkfilter_parent_class)->matches(filter, entity))
189         return FALSE;
190 
191     if (!osinfo_filter_matches(linkfilter->priv->targetFilter,
192                                OSINFO_ENTITY(osinfo_devicelink_get_target(OSINFO_DEVICELINK(entity)))))
193         return FALSE;
194 
195     return TRUE;
196 }
197