Handling Namespace Models (Classes) in Namespace

Handling namespace models (classes) in namespace

The

models/ns1/articles.rb

is basically setting the table name prefix for all the model classes under that namespace. Thats its use. It's more DRY'ish to do in there (in a single file), rather than setting the prefix in every model class under that namespace.

I am not a big fan of using namespaces in my models. However you could refer to the following articles to gain a better understanding about using namespaces in modules.

  • Namespaced models and controllers

Some alternatives to using namespaces in models

  • A simple alternative to namespaced models

Hope this helps.

Namespace and class with the same name?

I don't recommend you to name a class like its namespace, see this article.

The Framework Design Guidelines say in section 3.4 “do not use the
same name for a namespace and a type in that namespace”. That is:

namespace MyContainers.List 
{
public class List { … }
}

Why is this badness? Oh, let me count the ways.

You can get yourself into situations where you think you are referring
to one thing but in fact are referring to something else. Suppose you
end up in this unfortunate situation: you are writing Blah.DLL and
importing Foo.DLL and Bar.DLL, which, unfortunately, both have a type
called Foo:

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL:
namespace Bar { public class Foo { } }

// Blah.DLL:
namespace Blah
{
using Foo;
using Bar;
class C { Foo foo; }
}

The compiler gives an error. “Foo” is ambiguous between Foo.Foo and
Bar.Foo.
Bummer. I guess I’ll fix that by fully qualifying the name:

   class C { Foo.Foo foo; } 

This now gives the ambiguity error “Foo in
Foo.Foo is ambiguous between Foo.Foo and Bar.Foo
”. We still don’t know
what the first Foo refers to, and until we can figure that out, we
don’t even bother to try to figure out what the second one refers to.

rails how to properly move models to a namespace

I think you can try this:

create a new rails project, then run

rails g model Local::Address city:string country:string

Now you can see how rails handle namespace for model. You can just follow the way to modify yours.

How to handle same class name in different namespaces?


If i do that i will then need to specify the full namespace name before my static class in order to access it?

No, there is no need for that, though the details depend on the class that will use these types and the using declarations it has.

If you only use one of the namespaces in the class, there is no ambiguity and you can go ahead and use the type.

If you use both of the namespaces, you will either have to fully qualify the usages, or use namespace/type aliases to disambiguate the types.

using ERPUtils = MyCompany.ERP.Utilities;
using BCUtils = MyCompany.Barcode.Utilities;

public void MyMethod()
{
var a = ERPUtils.Method();
var b = BCUtils.Method();
}

Explicitly forcing Class reference to namespace does not work

I am going to close this question since it is more of a c# understanding thing and you normally shouldn't have models/classes named the same.

Those references are named "using alias directive" for anybody wondering.

Here is a link for the interested ones: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive

How do I namespace a model in Laravel so as not to clash with an existing class?

You just need to apply a namespace to it as you normally would. So, for example.

<?php namespace Models;

use Eloquent;

class Event extends Eloquent {

}

You should then correctly setup your composer.json so that it loads your models. You could use classmap or psr-0 for this, depending on whether or not you're following PSR-0 with your directory structure.

I'm pretty sure the models directory is already mapped.

Edit

As mentioned in the comments you must run composer dump-autoload.

Default namespace & complex package/data structure

Solution how get (write & read xml) the needed result:

<?xml version="1.0" encoding="UTF-8"?>
<xmlBoo xmlns="http://www.example.org/boo" xmlns:c="http://www.example.org/customer" xmlns:a="http://www.example.org/address" xmlns:h="http://www.example.org/header">
<h:header>
<h:id>101</h:id>
</h:header>
<c:customer>
<c:id>1</c:id>
<c:name>Yen</c:name>
<a:address>
<a:street>Long street</a:street>
</a:address>
</c:customer>
<someBooSpecificField>Specific data in Boo</someBooSpecificField>
</xmlBoo>
  • for root element and its "simple" children is used default namespace (without prefix)
  • for complex (objects in java) children are used different namespaces (mapped to different prefixes)
  • model classes are in different packages

So here is the solution:

Sample Image

Define MOXy implementation of JAXB, file: jaxb.properties

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Create abstract class for common fields, define namespace for object, file Xml.java

package example.xml;

@XmlTransient
public abstract class Xml {

private Header header;
private Customer customer;

@XmlElement(namespace="http://www.example.org/header")
public Header getHeader() {
return header;
}

public void setHeader(Header header) {
this.header = header;
}

@XmlElement(namespace="http://www.example.org/customer")
public Customer getCustomer() {
return customer;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}
}

Create "root" class, XmlBoo.java

package example.xml.boo;

@XmlRootElement
@XmlType(propOrder = {"header", "customer", "someBooSpecificField"})
public class XmlBoo extends Xml {

private String someBooSpecificField;

// getter & setter
}

Set namespace and QUALIFIED for "root" class, file: example.xml.boo.package-info.java

@XmlSchema(
namespace = "http://www.example.org/boo",
elementFormDefault = XmlNsForm.QUALIFIED)

package example.xml.boo;

Set QUALIFIED to generate prefix for children (the namespace will be overridden by namespace defined on the class, but it must be defined), file: example.model.package-info.java

@XmlSchema(
namespace = "http://www.example.org",
elementFormDefault = XmlNsForm.QUALIFIED)

package example.model;

Create Header.java

package example.model;

@XmlType(namespace = "http://www.example.org/header")
public class Header {

private long id;

// getter & setter
}

Create Customer.java

package example.model;

@XmlType(namespace = "http://www.example.org/customer", propOrder = {"id", "name", "address"})
public class Customer {

private long id;
private String name;
private Address address;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@XmlElement(namespace="http://www.example.org/address")
public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}
}

Create Address.java

package example.model;

@XmlType(namespace = "http://www.example.org/address")
public class Address {

private String street;

// getter & setter
}

Create MyNamespacePrefixMapper.java by extending org.eclipse.persistence.oxm.NamespacePrefixMapper

package example;
import org.eclipse.persistence.oxm.NamespacePrefixMapper;

public class MyNamespacePrefixMapper extends NamespacePrefixMapper {

private static final String BOO_PREFIX = ""; // DEFAULT NAMESPACE
private static final String BOO_URI = "http://www.example.org/boo";
private static final String FOO_PREFIX = ""; // DEFAULT NAMESPACE
private static final String FOO_URI = "http://www.example.org/foo";
private static final String HEADER_PREFIX = "h";
private static final String HEADER_URI = "http://www.example.org/header";
private static final String CUSTOMER_PREFIX = "c";
private static final String CUSTOMER_URI = "http://www.example.org/customer";
private static final String ADDRESS_PREFIX = "a";
private static final String ADDRESS_URI = "http://www.example.org/address";

@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {

switch (namespaceUri) {
case BOO_URI:
return BOO_PREFIX;
case FOO_URI:
return FOO_PREFIX;
case HEADER_URI:
return HEADER_PREFIX;
case CUSTOMER_URI:
return CUSTOMER_PREFIX;
case ADDRESS_URI:
return ADDRESS_PREFIX;
default:
return null;
}
}
}

Create XML

public static void generateBoo() {
try {
JAXBContext jc = JAXBContext.newInstance(XmlBoo.class);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, new MyNamespacePrefixMapper());

XmlBoo xmlBoo = new XmlBoo();
Header header = new Header();
header.setId(101);
xmlBoo.setHeader(header);

Customer customer = new Customer();
customer.setId(1);
customer.setName("Yen");
Address address = new Address();
address.setStreet("Long street");
customer.setAddress(address);
xmlBoo.setCustomer(customer);

xmlBoo.setSomeBooSpecificField("Specific data in Boo");

m.marshal(xmlBoo, System.out);
m.marshal(xmlBoo, new File("xml_boo.xml"));

} catch (JAXBException e) {
e.printStackTrace();
}
}

Read XML

public static void readBoo() {

Object element = null;

try {
JAXBContext jc = JAXBContext.newInstance(XmlBoo.class);
Unmarshaller u = jc.createUnmarshaller();
element = u.unmarshal(new File("xml_boo.xml"));

} catch (JAXBException e) {
e.printStackTrace();
}

if (element instanceof XmlBoo) {
XmlBoo xmlBoo = (XmlBoo) element;
Customer customer = xmlBoo.getCustomer();

System.out.println("INFO | xmlBoo field: [" + xmlBoo.getSomeBooSpecificField() + "]");
System.out.println("INFO | customer name: [" + customer.getName() + "]");
System.out.println("INFO | address street: [" + customer.getAddress().getStreet() + "]");

}
}


Related Topics



Leave a reply



Submit