Index: mojo/public/go/application/describer.go |
diff --git a/mojo/public/go/application/describer.go b/mojo/public/go/application/describer.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bf4911bfb157bebd9d67a4ba05faa9fd8c59ca6c |
--- /dev/null |
+++ b/mojo/public/go/application/describer.go |
@@ -0,0 +1,103 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package application |
+ |
+import ( |
+ "fmt" |
+ "log" |
+ |
+ "mojo/public/go/bindings" |
+ |
+ "mojo/public/interfaces/bindings/service_describer" |
+) |
+ |
+// ServiceDescriberFactory implements ServiceFactory for ServiceDescriber. |
+// For cleanup purposes, it is also the implementation of a ServiceDescriber. |
+type ServiceDescriberFactory struct { |
+ // mapping holds the map from interface names to ServiceDescription's. |
+ mapping map[string]service_describer.ServiceDescription |
+ // stubs stores the stubs for connections opened to this factory. |
+ stubs []*bindings.Stub |
+ // descriptionFactories maps interface names to ServiceDescriptionFactory's. |
+ descriptionFactories map[string]*ServiceDescriptionFactory |
+} |
+ |
+func newServiceDescriberFactory(mapping map[string]service_describer.ServiceDescription) *ServiceDescriberFactory { |
+ return &ServiceDescriberFactory{ |
+ mapping: mapping, |
+ descriptionFactories: make(map[string]*ServiceDescriptionFactory), |
+ } |
+} |
+ |
+func (sd *ServiceDescriberFactory) Create(request service_describer.ServiceDescriber_Request) { |
+ stub := service_describer.NewServiceDescriberStub(request, sd, bindings.GetAsyncWaiter()) |
+ sd.stubs = append(sd.stubs, stub) |
+ go func() { |
+ for { |
+ if err := stub.ServeRequest(); err != nil { |
+ connectionError, ok := err.(*bindings.ConnectionError) |
+ if !ok || !connectionError.Closed() { |
+ log.Println(err) |
+ } |
+ break |
+ } |
+ } |
+ }() |
+} |
+ |
+func (sd *ServiceDescriberFactory) Close() { |
+ for _, stub := range sd.stubs { |
+ stub.Close() |
+ } |
+ for _, factory := range sd.descriptionFactories { |
+ for _, stub := range factory.stubs { |
+ stub.Close() |
+ } |
+ } |
+} |
+ |
+// Helper method for DescribeService |
+func (sd *ServiceDescriberFactory) getServiceDescriptionFactory(inInterfaceName string) *ServiceDescriptionFactory { |
+ // Assumes the interface name is in the mapping. |
+ if desc, ok := sd.descriptionFactories[inInterfaceName]; ok { |
+ return desc |
+ } |
+ sd.descriptionFactories[inInterfaceName] = &ServiceDescriptionFactory{ |
+ impl: sd.mapping[inInterfaceName], |
+ } |
+ return sd.descriptionFactories[inInterfaceName] |
+} |
+ |
+func (sd *ServiceDescriberFactory) DescribeService(inInterfaceName string, inDescriptionRequest service_describer.ServiceDescription_Request) (err error) { |
+ if _, ok := sd.mapping[inInterfaceName]; ok { |
+ sd.getServiceDescriptionFactory(inInterfaceName).Create(inDescriptionRequest) |
+ return nil |
+ } |
+ return fmt.Errorf("The interface %s is unknown by this application", inInterfaceName) |
+} |
+ |
+// ServiceDescriptionFactory implements ServiceFactory for ServiceDescription. |
+type ServiceDescriptionFactory struct { |
+ // stubs stores the stubs for connections opened to this factory. |
+ stubs []*bindings.Stub |
+ // impl is the ServiceDescription implementation served by this factory. |
+ impl service_describer.ServiceDescription |
+} |
+ |
+func (serviceDescriptionFactory *ServiceDescriptionFactory) Create(request service_describer.ServiceDescription_Request) { |
+ stub := service_describer.NewServiceDescriptionStub(request, serviceDescriptionFactory.impl, bindings.GetAsyncWaiter()) |
+ serviceDescriptionFactory.stubs = append(serviceDescriptionFactory.stubs, stub) |
+ go func() { |
+ for { |
+ if err := stub.ServeRequest(); err != nil { |
+ connectionError, ok := err.(*bindings.ConnectionError) |
+ if !ok || !connectionError.Closed() { |
+ log.Println(err) |
+ } |
+ break |
+ } |
+ } |
+ }() |
+} |