diff --git a/src/main/java/ru/javaops/masterjava/Main.java b/src/main/java/ru/javaops/masterjava/Main.java index a849258..2c353f9 100644 --- a/src/main/java/ru/javaops/masterjava/Main.java +++ b/src/main/java/ru/javaops/masterjava/Main.java @@ -1,5 +1,20 @@ package ru.javaops.masterjava; +import com.google.common.io.Resources; +import jdk.internal.org.xml.sax.SAXException; +import ru.javaops.masterjava.xml.schema.ObjectFactory; +import ru.javaops.masterjava.xml.schema.Payload; +import ru.javaops.masterjava.xml.schema.Project; +import ru.javaops.masterjava.xml.schema.User; +import ru.javaops.masterjava.xml.util.JaxbParser; +import ru.javaops.masterjava.xml.util.Schemas; + +import javax.xml.bind.JAXBException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + /** * User: gkislin * Date: 05.08.2015 @@ -8,7 +23,48 @@ * @link https://github.com/JavaOPs/topjava */ public class Main { - public static void main(String[] args) { - System.out.format("Hello MasterJava!"); + private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); + static { + JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); + } + + public static void main(String[] args) throws IOException, JAXBException, org.xml.sax.SAXException { + // System.out.format("Hello MasterJava!"); + + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + Payload payload = JAXB_PARSER.unmarshal( + Resources.getResource("payload.xml").openStream()); + String str; + + + while (!(str=reader.readLine()).equals("exit")) + { + boolean found = false; + List list = payload.getProjects().getProject(); + for (Project project:list) + { + if (project.getName().equals(str)) + { + found=true; + List users = payload.getUsers().getUser(); + List groups = project.getGroups(); + SortedSet projectUsers = new TreeSet<>(); + for (Project.Groups group:groups) + {for (User u:users) + { + List userGroups = u.getGroups(); + for (Object uGroup:userGroups) { + Project.Groups ugr = (Project.Groups)uGroup; + if (ugr.getName().equals(group.getName())) + { + projectUsers.add(u.getFullName()); + } + } + }} + System.out.println(projectUsers); + } + } + if (!found)System.out.println("No such project"); + } } } diff --git a/src/main/java/ru/javaops/masterjava/StaxApp.java b/src/main/java/ru/javaops/masterjava/StaxApp.java new file mode 100644 index 0000000..fe738fa --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/StaxApp.java @@ -0,0 +1,137 @@ +package ru.javaops.masterjava; + +import com.google.common.io.Resources; +import ru.javaops.masterjava.xml.schema.FlagType; +import ru.javaops.masterjava.xml.schema.GroupType; +import ru.javaops.masterjava.xml.schema.Project; +import ru.javaops.masterjava.xml.schema.User; +import ru.javaops.masterjava.xml.util.StaxStreamProcessor; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Created by Котик on 12.03.2017. + */ +public class StaxApp { + private static boolean nameFlag; + private static boolean descFlag; + private static boolean fullNameFlag; + + public static void main(String[] args) throws IOException, XMLStreamException { + BufferedReader strReader = new BufferedReader(new InputStreamReader(System.in)); + try (StaxStreamProcessor processor = + new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { + XMLStreamReader reader = processor.getReader(); + + List projectList = new ArrayList<>(); + List userList = new ArrayList<>(); + Project project = null; + User user=null; + int event = reader.getEventType(); + // обходим весь XML файл + while (true) { + // проходим по типам событий + switch (event) { + case XMLStreamConstants.START_ELEMENT: + // в зависимости от имени тега отмечаем нужный фалг + if (reader.getLocalName().equals("Project")) { + project = new Project(); + project.setGroups(); + } else if (reader.getLocalName().equals("name")) { + nameFlag = true; + } else if (reader.getLocalName().equals("description")) { + descFlag = true; + } else if (reader.getLocalName().equals("groups")) { + Project.Groups group = new Project.Groups(); + group.setGroupType(GroupType.fromValue(reader.getAttributeValue(0))); + group.setName(reader.getAttributeValue(1)); + group.setId(reader.getAttributeValue(2)); + project.addGroup(group); + } + else if (reader.getLocalName().equals("User")) { + user = new User(); + user.setGroups(); + user.setFlag(FlagType.fromValue(reader.getAttributeValue(0))); + String groups = reader.getAttributeValue(3); + String[] gr = groups.split(" "); + for (String s:gr) + { + user.addGroup(s); + } + } + else if (reader.getLocalName().equals("fullName")) { + fullNameFlag = true; + } + break; + // сохраняем данные XML-элемента, + // флаг которого равен true в объект Student + case XMLStreamConstants.CHARACTERS: + if (nameFlag) { + project.setName(reader.getText()); + nameFlag = false; + } else if (descFlag) { + project.setDescription(reader.getText()); + descFlag = false; + } else if (fullNameFlag) { + user.setFullName(reader.getText()); + fullNameFlag=false; + } + break; + // если цикл дошел до закрывающего элемента узла Student, то сохраняем объект в список + case XMLStreamConstants.END_ELEMENT: + if (reader.getLocalName().equals("Project")) { + projectList.add(project); + } + else if (reader.getLocalName().equals("User")) + { + userList.add(user); + } + break; + } + // если больше элементов нет, то заканчиваем обход файла + if (!reader.hasNext()) + break; + + // переход к следующему событию + event = reader.next(); + } + + String str; + while (!(str=strReader.readLine()).equals("exit")) + { + boolean found = false; + for (Project p:projectList) + { + if (p.getName().equals(str)) + { + found=true; + List groups = p.getGroups(); + SortedSet projectUsers = new TreeSet<>(); + for (Project.Groups group:groups) + {for (User u:userList) + { + List userGroups = u.getGroups(); + for (Object uGroup:userGroups) { + if (uGroup.toString().equals(group.getName())) + { + projectUsers.add(u.getFullName()); + } + } + }} + System.out.println(projectUsers); + } + } + if (!found)System.out.println("No such project"); + } + } + } +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java b/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java new file mode 100644 index 0000000..d504164 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java @@ -0,0 +1,40 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for groupType. + * + *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <simpleType name="groupType">
+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     <enumeration value="REGISTERING"/>
+ *     <enumeration value="CURRENT"/>
+ *     <enumeration value="FINISHED"/>
+ *   </restriction>
+ * </simpleType>
+ * 
+ * + */ +@XmlType(name = "groupType", namespace = "http://javaops.ru") +@XmlEnum +public enum GroupType { + + REGISTERING, + CURRENT, + FINISHED; + + public String value() { + return name(); + } + + public static GroupType fromValue(String v) { + return valueOf(v); + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java index e8f105e..845442c 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java @@ -25,6 +25,7 @@ public class ObjectFactory { private final static QName _City_QNAME = new QName("http://javaops.ru", "City"); + private final static QName _ProjectGroup_QNAME = new QName("http://javaops.ru", "projectGroup"); /** * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: ru.javaops.masterjava.xml.schema @@ -33,6 +34,14 @@ public class ObjectFactory { public ObjectFactory() { } + /** + * Create an instance of {@link Project } + * + */ + public Project createProject() { + return new Project(); + } + /** * Create an instance of {@link Payload } * @@ -41,6 +50,14 @@ public Payload createPayload() { return new Payload(); } + /** + * Create an instance of {@link Project.Groups } + * + */ + public Project.Groups createProjectGroups() { + return new Project.Groups(); + } + /** * Create an instance of {@link User } * @@ -65,6 +82,14 @@ public Payload.Users createPayloadUsers() { return new Payload.Users(); } + /** + * Create an instance of {@link Payload.Projects } + * + */ + public Payload.Projects createPayloadProjects() { + return new Payload.Projects(); + } + /** * Create an instance of {@link CityType } * @@ -82,4 +107,13 @@ public JAXBElement createCity(CityType value) { return new JAXBElement(_City_QNAME, CityType.class, null, value); } + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://javaops.ru", name = "projectGroup") + public JAXBElement createProjectGroup(Object value) { + return new JAXBElement(_ProjectGroup_QNAME, Object.class, null, value); + } + } diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java index 2a62764..e581eb9 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java @@ -42,6 +42,17 @@ * </complexContent> * </complexType> * </element> + * <element name="Projects"> + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + * <sequence maxOccurs="unbounded" minOccurs="0"> + * <element ref="{http://javaops.ru}Project"/> + * </sequence> + * </restriction> + * </complexContent> + * </complexType> + * </element> * </all> * </restriction> * </complexContent> @@ -61,6 +72,8 @@ public class Payload { protected Payload.Cities cities; @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) protected Payload.Users users; + @XmlElement(name = "Projects", namespace = "http://javaops.ru", required = true) + protected Payload.Projects projects; /** * Gets the value of the cities property. @@ -110,6 +123,30 @@ public void setUsers(Payload.Users value) { this.users = value; } + /** + * Gets the value of the projects property. + * + * @return + * possible object is + * {@link Payload.Projects } + * + */ + public Payload.Projects getProjects() { + return projects; + } + + /** + * Sets the value of the projects property. + * + * @param value + * allowed object is + * {@link Payload.Projects } + * + */ + public void setProjects(Payload.Projects value) { + this.projects = value; + } + /** *

Java class for anonymous complex type. @@ -171,6 +208,66 @@ public List getCity() { } + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <sequence maxOccurs="unbounded" minOccurs="0">
+     *         <element ref="{http://javaops.ru}Project"/>
+     *       </sequence>
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "project" + }) + public static class Projects { + + @XmlElement(name = "Project", namespace = "http://javaops.ru") + protected List project; + + /** + * Gets the value of the project property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the project property. + * + *

+ * For example, to add a new item, do as follows: + *

+         *    getProject().add(newItem);
+         * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Project } + * + * + */ + public List getProject() { + if (project == null) { + project = new ArrayList(); + } + return this.project; + } + + } + + /** *

Java class for anonymous complex type. * diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Project.java b/src/main/java/ru/javaops/masterjava/xml/schema/Project.java new file mode 100644 index 0000000..12808c2 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/Project.java @@ -0,0 +1,268 @@ + +package ru.javaops.masterjava.xml.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlID; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <sequence maxOccurs="unbounded" minOccurs="0">
+ *           <element name="groups">
+ *             <complexType>
+ *               <complexContent>
+ *                 <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                   <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                   <attribute name="groupType" use="required" type="{http://javaops.ru}groupType" />
+ *                   <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *                 </restriction>
+ *               </complexContent>
+ *             </complexType>
+ *           </element>
+ *         </sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "name", + "description", + "groups" +}) +@XmlRootElement(name = "Project", namespace = "http://javaops.ru") +public class Project { + + @XmlElement(namespace = "http://javaops.ru", required = true) + protected String name; + @XmlElement(namespace = "http://javaops.ru", required = true) + protected String description; + @XmlElement(namespace = "http://javaops.ru") + protected List groups; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the description property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDescription() { + return description; + } + + /** + * Sets the value of the description property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDescription(String value) { + this.description = value; + } + + /** + * Gets the value of the groups property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the groups property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGroups().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Project.Groups } + * + * + */ + public List getGroups() { + if (groups == null) { + groups = new ArrayList(); + } + return this.groups; + } + + public void setGroups() + { + groups=new ArrayList<>(); + } + public void addGroup (Project.Groups group) + { + groups.add(group); + } + + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       <attribute name="groupType" use="required" type="{http://javaops.ru}groupType" />
+     *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "") + public static class Groups { + + @XmlAttribute(name = "name") + protected String name; + @XmlAttribute(name = "groupType", required = true) + protected GroupType groupType; + @XmlAttribute(name = "id", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + @XmlID + @XmlSchemaType(name = "ID") + protected String id; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the groupType property. + * + * @return + * possible object is + * {@link GroupType } + * + */ + public GroupType getGroupType() { + return groupType; + } + + /** + * Sets the value of the groupType property. + * + * @param value + * allowed object is + * {@link GroupType } + * + */ + public void setGroupType(GroupType value) { + this.groupType = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + + } + + @Override + public String toString() { + return "Project{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", groups=" + groups + + '}'; + } +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/User.java b/src/main/java/ru/javaops/masterjava/xml/schema/User.java index b3430ce..1d2416b 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/User.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/User.java @@ -1,6 +1,8 @@ package ru.javaops.masterjava.xml.schema; +import java.util.ArrayList; +import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -21,11 +23,12 @@ * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> - * <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/> * </sequence> + * <attribute name="email" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="flag" use="required" type="{http://javaops.ru}flagType" /> * <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" /> + * <attribute name="groups" type="{http://www.w3.org/2001/XMLSchema}IDREFS" /> * </restriction> * </complexContent> * </complexType> @@ -35,69 +38,72 @@ */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { - "email", "fullName" }) @XmlRootElement(name = "User", namespace = "http://javaops.ru") public class User { - @XmlElement(namespace = "http://javaops.ru", required = true) - protected String email; @XmlElement(namespace = "http://javaops.ru", required = true) protected String fullName; + @XmlAttribute(name = "email") + protected String email; @XmlAttribute(name = "flag", required = true) protected FlagType flag; @XmlAttribute(name = "city", required = true) @XmlIDREF @XmlSchemaType(name = "IDREF") protected Object city; + @XmlAttribute(name = "groups") + @XmlIDREF + @XmlSchemaType(name = "IDREFS") + protected List groups; /** - * Gets the value of the email property. + * Gets the value of the fullName property. * * @return * possible object is * {@link String } * */ - public String getEmail() { - return email; + public String getFullName() { + return fullName; } /** - * Sets the value of the email property. + * Sets the value of the fullName property. * * @param value * allowed object is * {@link String } * */ - public void setEmail(String value) { - this.email = value; + public void setFullName(String value) { + this.fullName = value; } /** - * Gets the value of the fullName property. + * Gets the value of the email property. * * @return * possible object is * {@link String } * */ - public String getFullName() { - return fullName; + public String getEmail() { + return email; } /** - * Sets the value of the fullName property. + * Sets the value of the email property. * * @param value * allowed object is * {@link String } * */ - public void setFullName(String value) { - this.fullName = value; + public void setEmail(String value) { + this.email = value; } /** @@ -148,4 +154,53 @@ public void setCity(Object value) { this.city = value; } + /** + * Gets the value of the groups property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the groups property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGroups().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Object } + * + * + */ + public List getGroups() { + if (groups == null) { + groups = new ArrayList(); + } + return this.groups; + } + + public void setGroups() + { + groups=new ArrayList<>(); + } + + public void addGroup(Object group) + { + groups.add(group); + } + + @Override + public String toString() { + return "User{" + + "fullName='" + fullName + '\'' + + ", email='" + email + '\'' + + ", flag=" + flag + + ", city=" + city + + ", groups=" + groups + + '}'; + } } diff --git a/src/main/resources/payload.xml b/src/main/resources/payload.xml new file mode 100644 index 0000000..bb14058 --- /dev/null +++ b/src/main/resources/payload.xml @@ -0,0 +1,35 @@ + + + + Full Name + + + Admin + + + Deleted + + + + Санкт-Петербург + Киев + Минск + + + + + topjava + spring + + + + + masterjava + multithreading + + + + + \ No newline at end of file diff --git a/src/main/resources/payload.xsd b/src/main/resources/payload.xsd index 9ef1e46..c18fffb 100644 --- a/src/main/resources/payload.xsd +++ b/src/main/resources/payload.xsd @@ -21,6 +21,14 @@ + + + + + + + + @@ -28,11 +36,12 @@ - + + @@ -53,4 +62,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/payload.xml b/src/test/resources/payload.xml index 796e99c..bb14058 100644 --- a/src/test/resources/payload.xml +++ b/src/test/resources/payload.xml @@ -2,16 +2,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://javaops.ru payload.xsd"> - - gmail@gmail.com + Full Name - - admin@javaops.ru + Admin - - mail@yandex.ru + Deleted @@ -20,4 +17,19 @@ Киев Минск + + + + topjava + spring + + + + + masterjava + multithreading + + + + \ No newline at end of file