ruby-xes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ module XES
2
+ # Classifier represents "classifier" element of XES.
3
+ class Classifier
4
+ # @return [String]
5
+ # classifier name
6
+ attr_reader :name
7
+
8
+ # @return [String]
9
+ # classifier keys
10
+ attr_reader :keys
11
+
12
+ # Create a XES classifier element.
13
+ #
14
+ # @param name [String]
15
+ # classifier name
16
+ # @param keys [String]
17
+ # classifier keys
18
+ def initialize(name, keys)
19
+ @name = name
20
+ @keys = keys
21
+ end
22
+
23
+ # Return true if the element is formattable.
24
+ #
25
+ # @return [Boolean]
26
+ # true if the element is formattable
27
+ def formattable?
28
+ not(@name.nil? or @keys.nil?)
29
+ end
30
+
31
+ # Format as a XML element.
32
+ #
33
+ # @return [REXML::Element]
34
+ # XML element
35
+ def format
36
+ raise FormatError.new(self) unless formattable?
37
+
38
+ REXML::Element.new("classifier").tap do |ext|
39
+ ext.attributes["name"] = @name
40
+ ext.attributes["keys"] = @keys
41
+ end
42
+ end
43
+
44
+ # @api private
45
+ def ==(other)
46
+ return false unless other.kind_of?(self.class)
47
+ @name == other.name and @keys == other.keys
48
+ end
49
+ alias :eql? :"=="
50
+
51
+ # @api private
52
+ def hash
53
+ @name.hash + @keys.hash
54
+ end
55
+ end
56
+
57
+ # known XES classifier elements
58
+ CLASSIFIER = {
59
+ :mxml_legacy_classifier => Classifier.new("MXML Legacy Classifier", "concept:name lifecycle:transition"),
60
+ :event_name => Classifier.new("Event Name", "concept:name"),
61
+ :resource => Classifier.new("Resource", "org:resource")
62
+ }
63
+ end
@@ -0,0 +1,48 @@
1
+ module XES
2
+ # Document is a class for XES event log doucment.
3
+ class Document
4
+ # @return [Log]
5
+ # log element
6
+ attr_accessor :log
7
+
8
+ # @param log [Log]
9
+ def initialize(log=nil)
10
+ @log = log
11
+ end
12
+
13
+ # Return true if the document is formattable.
14
+ #
15
+ # @return [Boolean]
16
+ # true if the element is formattable
17
+ def formattable?
18
+ not(@log.nil?) and @log.formattable?
19
+ end
20
+
21
+ # Format as a XML document.
22
+ #
23
+ # @return [REXML::Document]
24
+ # XML document
25
+ # @raise FormatError
26
+ # format error when the document is not formattable
27
+ def format
28
+ raise FormatError.new(self) unless formattable?
29
+
30
+ REXML::Document.new.tap do |doc|
31
+ doc << REXML::XMLDecl.new
32
+ doc.elements << @log.format
33
+ end
34
+ end
35
+
36
+ # @api private
37
+ def ==(other)
38
+ return false unless other.kind_of?(self.class)
39
+ @log == other.log
40
+ end
41
+ alias :eql? :"=="
42
+
43
+ # @api private
44
+ def hash
45
+ @attributes.hash + @events.hash
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ module XES
2
+ # XESEvent represents "event" element of XES.
3
+ class Event
4
+ include EventAttributeAccessor
5
+
6
+ # @return [Array<Attribute>]
7
+ # event attributes
8
+ attr_accessor :attributes
9
+
10
+ # Create a XES event.
11
+ #
12
+ # @param attributes [Array<Attribute>]
13
+ # attributes of the event
14
+ def initialize(attributes=[])
15
+ @attributes = attributes
16
+ end
17
+
18
+ # Return true if the element is formattable.
19
+ #
20
+ # @return [Boolean]
21
+ # true if the element is formattable
22
+ def formattable?
23
+ not(@attributes.empty?)
24
+ end
25
+
26
+ # Format as a XML element.
27
+ #
28
+ # @return [REXML::Element]
29
+ # XML element
30
+ def format
31
+ REXML::Element.new("event").tap do |event|
32
+ @attributes.each do |attribute|
33
+ event.elements << attribute.format if attribute.formattable?
34
+ end
35
+ end
36
+ end
37
+
38
+ # @api private
39
+ def ==(other)
40
+ return false unless other.kind_of?(self.class)
41
+ @attributes == other.attributes
42
+ end
43
+ alias :eql? :"=="
44
+
45
+ # @api private
46
+ def hash
47
+ @attributes.hash
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,73 @@
1
+ module XES
2
+ # Extension represents "extension" element of XES.
3
+ class Extension
4
+ # @return [String]
5
+ # extension name
6
+ attr_reader :name
7
+
8
+ # @return [String]
9
+ # extension prefix
10
+ attr_reader :prefix
11
+
12
+ # @return [String]
13
+ # extension URI
14
+ attr_reader :uri
15
+
16
+ # Create a XES extension element.
17
+ #
18
+ # @param name [String]
19
+ # extension name
20
+ # @param prefix [String]
21
+ # extension prefix
22
+ # @param uri [String]
23
+ # extension definition URI
24
+ def initialize(name, prefix, uri)
25
+ @name = name
26
+ @prefix = prefix
27
+ @uri = uri
28
+ end
29
+
30
+ # Return true if the element is formattable.
31
+ #
32
+ # @return [Boolean]
33
+ # true if the element is formattable
34
+ def formattable?
35
+ not(@name.nil? or @prefix.nil? or @uri.nil?)
36
+ end
37
+
38
+ # Format as a XML element.
39
+ #
40
+ # @return [REXML::Element]
41
+ # XML element
42
+ def format
43
+ raise FormatError.new(self) unless formattable?
44
+
45
+ REXML::Element.new("extension").tap do |ext|
46
+ ext.attributes["name"] = @name
47
+ ext.attributes["prefix"] = @prefix
48
+ ext.attributes["uri"] = @uri
49
+ end
50
+ end
51
+
52
+ # @api private
53
+ def ==(other)
54
+ return false unless other.kind_of?(self.class)
55
+ @name == other.name and @prefix == other.prefix and @uri == other.uri
56
+ end
57
+ alias :eql? :"=="
58
+
59
+ # @api private
60
+ def hash
61
+ @name.hash + @prefix.hash + @uri.hash
62
+ end
63
+ end
64
+
65
+ # known XES extension elements
66
+ EXTENSION = {
67
+ :concept => Extension.new("Concept", "concept", "http://www.xes-standard.org/concept.xesext"),
68
+ :identity => Extension.new("Identity", "identity", "http://www.xes-standard.org/identity.xesext"),
69
+ :time => Extension.new("Time", "time", "http://www.xes-standard.org/time.xesext"),
70
+ :lifecycle => Extension.new("Lifecycle", "lifecycle", "http://www.xes-standard.org/lifecycle.xesext"),
71
+ :organizational => Extension.new("Organizational", "org", "http://www.xes-standard.org/org.xesext")
72
+ }
73
+ end
@@ -0,0 +1,15 @@
1
+ module XES
2
+ # FormatError is raised when you failed to format XES element.
3
+ class FormatError < StandardError
4
+ # @param element [Object]
5
+ # object that caused to raise this exception
6
+ def initialize(element)
7
+ @element = element
8
+ end
9
+
10
+ # @api private
11
+ def message
12
+ "Error happened on formatting %s" % @element.inspect
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ module XES
2
+ # Global represents "global" element of XES.
3
+ class Global
4
+ class << self
5
+ # Create an event global. The object extended by EventAttributeAccessor.
6
+ #
7
+ # @param attributes [Array<Attribute>]
8
+ # event global attributes
9
+ def event(attributes=[])
10
+ new("event", attributes).tap do |global|
11
+ global.extend EventAttributeAccessor
12
+ end
13
+ end
14
+
15
+ # Create a trace global. The object extended by TraceAttributeAccessor.
16
+ #
17
+ # @param attributes [Array<Attribute>]
18
+ # trace global attributes
19
+ def trace(attributes=[])
20
+ new("trace", attributes).tap do |global|
21
+ global.extend TraceAttributeAccessor
22
+ end
23
+ end
24
+ end
25
+
26
+ # @return [String]
27
+ # scope name
28
+ attr_reader :scope
29
+
30
+ # @return [Array<Attribute>]
31
+ # global attributes
32
+ attr_accessor :attributes
33
+
34
+ # @param scope [String]
35
+ # scope of global attributes
36
+ # @param attributes [Arrray<Attribute>]
37
+ # global attributes
38
+ def initialize(scope, attributes=[])
39
+ @scope = scope
40
+ @attributes = attributes
41
+ end
42
+
43
+ # Return true if the element is formattable.
44
+ #
45
+ # @return [Boolean]
46
+ # true if the element is formattable
47
+ def formattable?
48
+ not(@attributes.empty?)
49
+ end
50
+
51
+ # Format as a XML element.
52
+ #
53
+ # @return [REXML::Element]
54
+ # XML element
55
+ def format
56
+ raise FormatError.new(self) unless formattable?
57
+
58
+ REXML::Element.new("global").tap do |global|
59
+ global.attributes["scope"] = @scope.to_s
60
+ @attributes.each {|attribute| global.elements << attribute.format}
61
+ end
62
+ end
63
+
64
+ # @api private
65
+ def ==(other)
66
+ @scope == other.scope and @attributes == other.attributes
67
+ end
68
+ alias :eql? :"=="
69
+
70
+ # @api private
71
+ def hash
72
+ @scope.hash + @attributes.hash
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,158 @@
1
+ module XES
2
+ # Log represents log element of XES.
3
+ class Log
4
+ extend AttributeAccessor
5
+
6
+ # @!attribute [rw] concept_name
7
+ # @return [String]
8
+ # the value of attribute "concept:name"
9
+ define_attribute "concept:name", "string"
10
+
11
+ # @!attribute [rw] lifecycle_model
12
+ # @return [String]
13
+ # the value of attribute "lifecycle:model"
14
+ define_attribute "lifecycle:model", "string"
15
+
16
+ # @!attribute [rw] semantic_modelReference
17
+ # @return [String]
18
+ # the value of attribute "semantic:modelReference"
19
+ define_attribute "semantic:modelReference", "string"
20
+
21
+ # @!attribute [rw] identity_id
22
+ # @return [String]
23
+ # the value of attribute "identity:id"
24
+ define_attribute "identity:id", "id"
25
+
26
+ class << self
27
+ # Create new instance with default values.
28
+ #
29
+ # @return [Log]
30
+ # new log instance
31
+ def default
32
+ new.tap do |log|
33
+ log.xes_version = "1.4"
34
+ log.xes_features = "nested-attributes"
35
+ log.openxes_version = "1.0RC7"
36
+ log.extensions = [
37
+ EXTENSION[:concept],
38
+ EXTENSION[:identity],
39
+ EXTENSION[:time],
40
+ EXTENSION[:lifecycle],
41
+ EXTENSION[:organizational],
42
+ ]
43
+ log.classifiers = [
44
+ CLASSIFIER[:mxml_legacy_classifier],
45
+ CLASSIFIER[:event_name],
46
+ CLASSIFIER[:resource]
47
+ ]
48
+ end
49
+ end
50
+ end
51
+
52
+ # @return [String]
53
+ # XES version
54
+ attr_accessor :xes_version
55
+
56
+ # @return [String]
57
+ # XES features
58
+ attr_accessor :xes_features
59
+
60
+ # @return [String]
61
+ # openxes version for faking ProM
62
+ attr_accessor :openxes_version
63
+
64
+ # @return [String]
65
+ # xmlns value
66
+ attr_accessor :xmlns
67
+
68
+ # @return [Array<Extension>]
69
+ # XES extensions
70
+ attr_accessor :extensions
71
+
72
+ # @return [Array<Classifier>]
73
+ # XES classifiers
74
+ attr_accessor :classifiers
75
+
76
+ # @return [Array<Global>]
77
+ # XES global elements for event attributes
78
+ attr_accessor :event_global
79
+
80
+ # @return [Array<Global>]
81
+ # XES global elements for trace attributes
82
+ attr_accessor :trace_global
83
+
84
+ # @return [Array<Attribute>]
85
+ # XES attribute elements
86
+ attr_accessor :attributes
87
+
88
+ # @return [Array<XESTrace>]
89
+ # XES trace elements
90
+ attr_accessor :traces
91
+
92
+ def initialize
93
+ @xes_version = "1.4"
94
+ @xes_features = ""
95
+ @openxes_version = nil
96
+ @xmlns = "http://www.xes-standard.org/"
97
+ @extensions = []
98
+ @event_global = Global.event
99
+ @trace_global = Global.trace
100
+ @classifiers = []
101
+ @attributes = []
102
+ @traces = []
103
+ end
104
+
105
+ # Return true if the element is formattable.
106
+ #
107
+ # @return [Boolean]
108
+ # true if the element is formattable
109
+ def formattable?
110
+ @traces.any? {|trace| trace.formattable?}
111
+ end
112
+
113
+ # Format as a XML element.
114
+ #
115
+ # @return [REXML::Element]
116
+ # XML element
117
+ # @raise FormatError
118
+ # format error when the log is formattable
119
+ def format
120
+ raise FormatError.new(self) unless formattable?
121
+
122
+ REXML::Element.new("log").tap do |log|
123
+ log.attributes["xes.version"] = @xes_version.to_s if @xes_version
124
+ log.attributes["xes.features"] = @xes_features.to_s if @xes_features
125
+ log.attributes["openxes.version"] = @openxes_version.to_s if @openxes_version
126
+ log.attributes["xmlns"] = @xmlns.to_s if @xmlns
127
+ @extensions.each {|ext| log.elements << ext.format if ext.formattable?}
128
+ @classifiers.each {|classifier| log.elements << classifier.format if classifier.formattable?}
129
+ log.elements << @event_global.format if @event_global.formattable?
130
+ log.elements << @trace_global.format if @trace_global.formattable?
131
+ @attributes.each {|attribute| log.elements << attribute.format if attribute.formattable?}
132
+ @traces.each {|trace| log.elements << trace.format if trace.formattable?}
133
+ end
134
+ end
135
+
136
+ # @api private
137
+ def ==(other)
138
+ return false unless other.kind_of?(self.class)
139
+ return false unless @xes_version == other.xes_version
140
+ return false unless @xes_features == other.xes_features
141
+ return false unless @openxes_version == other.openxes_version
142
+ return false unless @xmlns == other.xmlns
143
+ return false unless @extensions == other.extensions
144
+ return false unless @event_global == other.event_global
145
+ return false unless @trace_global == other.trace_global
146
+ return false unless @classifiers == other.classifiers
147
+ return false unless @attributes == other.attributes
148
+ return false unless @traces == other.traces
149
+ return true
150
+ end
151
+ alias :eql? :"=="
152
+
153
+ # @api private
154
+ def hash
155
+ @attributes.hash + @events.hash
156
+ end
157
+ end
158
+ end