blob: f3619d43ebb3a05e240ad30356634b1796e239db [file] [log] [blame]
Andreas Wundsam27303462013-07-16 12:52:35 -07001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28"""
29@brief Main Java Generation module
30"""
31
32import pdb
33import os
34import shutil
35
36import of_g
37from loxi_ir import *
38import lang_java
Andreas Wundsame916d6f2013-07-30 11:33:58 -070039import test_data
Andreas Wundsam27303462013-07-16 12:52:35 -070040
41import loxi_utils.loxi_utils as loxi_utils
42
43import java_gen.java_model as java_model
44
45def gen_all_java(out, name):
Andreas Wundsamd83883e2013-07-25 14:50:51 -070046 basedir= '%s/openflowj' % of_g.options.install_dir
Andreas Wundsam27303462013-07-16 12:52:35 -070047 print "Outputting to %s" % basedir
48 if os.path.exists(basedir):
49 shutil.rmtree(basedir)
50 os.makedirs(basedir)
51 copy_prewrite_tree(basedir)
52
Andreas Wundsame916d6f2013-07-30 11:33:58 -070053 gen = JavaGenerator(basedir)
Andreas Wundsam27303462013-07-16 12:52:35 -070054 gen.create_of_interfaces()
55 gen.create_of_classes()
56 gen.create_of_const_enums()
Andreas Wundsam5204de22013-07-30 11:34:45 -070057 gen.create_of_factories()
Andreas Wundsam27303462013-07-16 12:52:35 -070058
Andreas Wundsamd83883e2013-07-25 14:50:51 -070059 with open('%s/README.java-lang' % os.path.dirname(__file__)) as readme_src:
Andreas Wundsam27303462013-07-16 12:52:35 -070060 out.writelines(readme_src.readlines())
61 out.close()
62
63
64class JavaGenerator(object):
65 templates_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'templates')
66
67 def __init__(self, basedir):
68 self.basedir = basedir
69 self.java_model = java_model.model
70
Andreas Wundsame916d6f2013-07-30 11:33:58 -070071 def render_class(self, clazz, template, src_dir=None, **context):
72 if not src_dir:
73 src_dir = "src/main/java/"
74
Andreas Wundsam27303462013-07-16 12:52:35 -070075 context['class_name'] = clazz.name
76 context['package'] = clazz.package
Andreas Wundsamd10e1c52013-08-01 22:02:49 -070077 context['template_dir'] = self.templates_dir
Andreas Wundsam27303462013-07-16 12:52:35 -070078
Andreas Wundsame916d6f2013-07-30 11:33:58 -070079 filename = os.path.join(self.basedir, src_dir, "%s/%s.java" % (clazz.package.replace(".", "/"), clazz.name))
Andreas Wundsam27303462013-07-16 12:52:35 -070080 dirname = os.path.dirname(filename)
81 if not os.path.exists(dirname):
82 os.makedirs(dirname)
83 prefix = '//::(?=[ \t]|$)'
84 print "filename: %s" % filename
85 with open(filename, "w") as f:
86 loxi_utils.render_template(f, template, [self.templates_dir], context, prefix=prefix)
87
88 def create_of_const_enums(self):
89 for enum in self.java_model.enums:
90 if enum.name in ["OFPort"]:
91 continue
92 self.render_class(clazz=enum,
93 template='const.java', enum=enum, all_versions=self.java_model.versions)
94
Andreas Wundsambf1dbbd2013-07-30 11:07:59 -070095 for version in enum.versions:
96 clazz = java_model.OFGenericClass(package="org.openflow.protocol.ver{}".format(version.of_version), name="{}SerializerVer{}".format(enum.name, version.of_version))
97 self.render_class(clazz=clazz, template="const_serializer.java", enum=enum, version=version)
98
Andreas Wundsam27303462013-07-16 12:52:35 -070099 def create_of_interfaces(self):
100 """ Create the base interfaces for of classes"""
101 for interface in self.java_model.interfaces:
102 #if not utils.class_is_message(interface.c_name):
103 # continue
104 self.render_class(clazz=interface,
105 template="of_interface.java", msg=interface)
106
107 def create_of_classes(self):
108 """ Create the OF classes with implementations for each of the interfaces and versions """
109 for interface in self.java_model.interfaces:
Andreas Wundsam27303462013-07-16 12:52:35 -0700110 for java_class in interface.versioned_classes:
Andreas Wundsam001b1822013-08-02 22:25:55 -0700111 if self.java_model.generate_class(java_class):
112 if not java_class.is_virtual:
113 self.render_class(clazz=java_class,
114 template='of_class.java', version=java_class.version, msg=java_class,
115 impl_class=java_class.name)
Andreas Wundsam27303462013-07-16 12:52:35 -0700116
Andreas Wundsam001b1822013-08-02 22:25:55 -0700117 self.create_unit_test(java_class.unit_test)
118 else:
119 disc = java_class.discriminator
120 if disc:
121 self.render_class(clazz=java_class,
122 template='of_virtual_class.java', version=java_class.version, msg=java_class,
123 impl_class=java_class.name, model=self.java_model)
124 else:
125 print "Class %s virtual but no discriminator" % java_class.name
126 else:
127 print "Class %s ignored by generate_class" % java_class.name
Andreas Wundsame916d6f2013-07-30 11:33:58 -0700128
129 def create_unit_test(self, unit_test):
130 if unit_test.has_test_data:
131 self.render_class(clazz=unit_test,
132 template='unit_test.java', src_dir="src/test/java",
133 version=unit_test.java_class.version,
134 test=unit_test, msg=unit_test.java_class,
135 test_data=unit_test.test_data)
136
137 def create_of_factories(self):
138 factory = self.java_model.of_factory
139 self.render_class(clazz=factory, template="of_factory_interface.java", factory=factory)
140 for factory_class in factory.factory_classes:
141 self.render_class(clazz=factory_class, template="of_factory_class.java", factory=factory_class, model=self.java_model)
142 self.render_class(clazz=java_model.OFGenericClass(package="org.openflow.protocol", name="OFFactories"), template="of_factories.java", versions=self.java_model.versions)
143
Andreas Wundsam27303462013-07-16 12:52:35 -0700144def copy_prewrite_tree(basedir):
145 """ Recursively copy the directory structure from ./java_gen/pre-write
146 into $basedir"""
147 print "Copying pre-written files into %s" % basedir
Andreas Wundsamac285ba2013-07-24 20:29:42 -0700148 #subprocess.call("cd java_gen/pre-written && tar cpf - pom.xml | ( cd ../../%s && tar xvpf - )" % basedir,
149 # shell=True)
Andreas Wundsamd83883e2013-07-25 14:50:51 -0700150 os.symlink(os.path.abspath("%s/pre-written/pom.xml" % os.path.dirname(__file__)), "%s/pom.xml" % basedir)